Delayed Expressions Fall 2017 Discussion 9: November 8, Iterables and Iterators. For Loops. Other Iterable Uses

Similar documents
ITERATORS AND STREAMS 9

Macros & Streams Spring 2018 Discussion 9: April 11, Macros

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

TAIL CALLS, ITERATORS, AND GENERATORS 11

ITERATORS AND GENERATORS 10

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Fall 2017 December 4, Scheme. Instructions

Fall 2017 December 4, 2017

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

SCHEME AND CALCULATOR 5b

INTERPRETERS 8. 1 Calculator COMPUTER SCIENCE 61A. November 3, 2016

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Intro. Scheme Basics. scm> 5 5. scm>

Structure and Interpretation of Computer Programs

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Python: Functions and Generators. Giuseppe Attardi

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

CS450 - Structure of Higher Level Languages

Iterators & Generators

TAIL RECURSION, SCOPE, AND PROJECT 4 11

Project 2: Scheme Interpreter

61A LECTURE 22 TAIL CALLS, ITERATORS. Steven Tang and Eric Tzeng July 30, 2013

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

Introduction to Functional Programming

Recursion & Iteration

Structure and Interpretation of Computer Programs

An introduction to Scheme

Functional Programming. Pure Functional Programming

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Streams. CS21b: Structure and Interpretation of Computer Programs Spring Term, 2004

Sample Final Exam Questions

Lisp Basic Example Test Questions

Advanced topics, part 2

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

INTERPRETERS AND TAIL CALLS 9

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Structure and Interpretation of Computer Programs

Random Testing in 321

F21SC Industrial Programming: Functional Programming in Python

Scheme Basics > (butfirst '(help!)) ()

Types of recursion. Structural vs. general recursion. Pure structural recursion. Readings: none. In this module: learn to use accumulative recursion

Lecture 21: Functional Programming in Python. List Comprehensions

Extra Lecture #7: Defining Syntax

Structure and Interpretation of Computer Programs

Random Testing in 321

Structure and Interpretation of Computer Programs

Functional Programming

Functional Programming. Pure Functional Languages

Problem Set 4: Streams and Lazy Evaluation

CS 61A Discussion 8: Scheme. March 23, 2017

Administrative Stuff

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Functional programming in LISP

An Explicit-Continuation Metacircular Evaluator

Organization of Programming Languages CS3200/5200N. Lecture 11

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Structure and Interpretation of Computer Programs

Streams and Evalutation Strategies

ITERATORS, GENERATORS, GENERIC FUNCTIONS

Programming Principles

Structure and Interpretation of Computer Programs

ITERATORS, GENERATORS, GENERIC FUNCTIONS

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

User-defined Functions. Conditional Expressions in Scheme

More About Recursive Data Types

CS115 INTRODUCTION TO COMPUTER SCIENCE 1. Additional Notes Module 5

RACKET BASICS, ORDER OF EVALUATION, RECURSION 1

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

PROBLEM SOLVING 11. July 24, 2012

Functional Programming. Pure Functional Languages

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream? 2. How does memoization work?

Programming Paradigms

April 2 to April 4, 2018

Functional Programming - 2. Higher Order Functions

LECTURE 16. Functional Programming

HIERARCHICAL DATA What is a Tree? How is it different from a Deep List? When would you use one over the other?

Y-Combinator. Contents. 1 Introduction. Avi Hayoun, Hodai Goldman and Lior Zur-Lotan. November 24, Terms recap. 1.2 Y-Combinator notes

CS1 Recitation. Week 2

Introduction to Scheme

Control and Environments Fall 2017 Discussion 1: August 30, Control. If statements. Boolean Operators

Repetition Through Recursion

Types of recursion. Readings: none. In this module: a glimpse of non-structural recursion. CS 135 Winter : Types of recursion 1

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

Structure and Interpretation of Computer Programs

Documentation for LISP in BASIC

Homework 1. Notes. What To Turn In. Unix Accounts. Reading. Handout 3 CSCI 334: Spring, 2017

Functional Programming Languages (FPL)

Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

CS61A Lecture 36. Soumya Basu UC Berkeley April 15, 2013

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

CSE Programming Languages Final exam - Winter Answer Key

Principles of Programming Languages

Building a system for symbolic differentiation

University of Massachusetts Lowell

Transcription:

CS 6A Delayed Expressions Fall 07 Discussion 9: November 8, 07 Iterables and Iterators An iterable is any container that can be processed sequentially. Examples include lists, tuples, strings, and dictionaries. Often we want to access the elements of an iterable, one at a time. We find ourselves writing lst[0], lst[], lst[], and so on. It would be more convenient if there was an object that could do this for us, so that we don t have to keep track of the indices. This is where iterators come in. Given an iterable, we can call the iter function on that iterable to return a new iterator object. Each time we call next on the iterator object, it gives us one element at a time, just like we wanted. When it runs out of elements to give, calling next on the iterator object will raise a StopIteration exception. We can create as many iterators as we would like from a single iterable. But, each iterator goes through the elements of the iterable only once. If you want to go through an iterable twice, create two iterators! For Loops By now, you are familiar with using for loops to iterate over iterables like lists and dictionaries. This only works because the for loop implicitly creates an iterator using the builtin iter function. Python then calls next repeatedly on the iterator, until it raises StopIteration. The code to the right is (basically) equivalent to using a for loop to iterate over a list of [,, 3]. Other Iterable Uses We have already encountered functions that use and create iterables. Here are some that we have seen (and some that we have not): ˆ range(start, end) - Creates iterable of numbers from start (inclusive) to end (exclusive) >>> lst = [4, ] >>> i = iter(lst) >>> j = iter(lst) >>> i <list_iterator object> 4 >>> next(j) 4 StopIteration >>> next(j) >>> counts = [,, 3] >>> items = iter(counts) >>> try:... while True:... item = next(items)... print(item)... except StopIteration:... pass # Do nothing... 3 ˆ map(f, iterable) - Creates iterator over f(x) for x in iterable ˆ filter(f, iterable) - Creates iterator over x for x in iterable if f(x) ˆ zip(iter, iter) - Creates iterator over co-indexed pairs (x, y) ˆ reversed(iterable) - Creates iterator sequence in reverse order ˆ list(iterable) - Creates a list containing all x in iterable ˆ tuple(iterable) - Creates a tuple containing all x in iterable

Delayed Expressions ˆ sorted(iterable) - Creates a sorted list containing all x in iterable Questions. What would Python display? >>> lst = [[, ]] >>> i = iter(lst) >>> j = iter(next(i)) >>> next(j) >>> lst.append(3) >>> next(j) Generators A generator function is a special kind of Python function that uses a yield statement instead of a return statement to report values. When a generator function is called, it returns an iterator. To the right, you can see a function that returns an iterator over the natural numbers.. yield The yield statement is similar to a return statement. However, while a return statement closes the current frame after the function exits, a yield statement causes the frame to be saved until the next time next is called, which allows the generator to automatically keep track of the iteration state. Once next is called again, execution resumes where it last stopped and continues until the next yield statement or the end of the function. A generator function can have multiple yield statements. >>> def gen_naturals():... current = 0... while True:... yield current... current += >>> gen = gen_naturals() >>> gen <generator object gen at...> >>> next(gen) 0 >>> next(gen) Including a yield statement in a function automatically tells Python that this function will create a generator. When we call the function, it returns a generator object instead of executing the the body. When the generator s next method is called, the body is executed until the next yield statement is executed.. yield from When yield from is called on an iterator, it will yield every value from that iterator. It s similar to doing the following: for x in an_iterator: yield x >>> square = lambda x: x*x >>> def many_squares(s):... for x in s:... yield square(x)... yield from [square(x) \ for x in s]... yield from map(square, s)... >>> list(many_squares([,, 3])) [, 4, 9,, 4, 9,, 4, 9]

Delayed Expressions 3 The example to the right demonstrates different ways of accomplishing the same result.

4 Delayed Expressions Questions. Write a generator function combiner that combines two input iterators using a given combiner function. The resulting iterator should have a size equal to the size of the shorter of its two input iterators. >>> from operator import add >>> evens = combiner(gen_naturals(), gen_naturals(), add) >>> next(evens) 0 >>> next(evens) >>> next(evens) 4 def combiner(iterator, iterator, combiner):. What is the result of executing this sequence of commands? >>> nats = gen_naturals() >>> doubled_nats = combiner(nats, nats, add) >>> next(doubled_nats) >>> next(doubled_nats).3 Write a generator function gen_all_items that takes a list of iterators and yields items from all of them in order. def gen_all_items(lst): """ >>> nums = [[, ], [3, 4], [[5, 6]]] >>> num_iters = [iter(l) for l in nums] >>> list(gen_all_items(num_iters)) [,, 3, 4, [5, 6]] """

Delayed Expressions 5.4 Write a generator function generate_subsets that returns all subsets of the positive integers from to n. Each call to this generator s next method will return a list of subsets of the set [,,..., n], where n is the number of previous calls to next. def generate_subsets(): """ >>> subsets = generate_subsets() >>> for _ in range(3):... print(next(subsets))... [[]] [[], []] [[], [], [], [, ]] """ 3 Streams In Python, we can use iterators to represent infinite sequences (for example, the generator for all natural numbers). However, Scheme does not support iterators. Let s see what happens when we try to use a Scheme list to represent an infinite sequence of natural numbers: scm> (define (naturals n) (cons n (naturals (+ n )))) naturals scm> (naturals 0) Error: maximum recursion depth exceeded Because the second argument to cons is always evaluated, we cannot create an infinite sequence of integers using a Scheme list. Instead, our Scheme interpreter supports streams, which are lazy Scheme lists. The first element is represented explicitly, but the rest of the stream s elements are computed only when needed. Computing a value only when it s needed is also known as lazy evaluation. scm> (define (naturals n) (cons-stream n (naturals (+ n )))) naturals scm> (define nat (naturals 0)) nat scm> (car nat) 0 scm> (car (cdr-stream nat)) scm> (car (cdr-stream (cdr-stream nat)))

6 Delayed Expressions We use the special form cons-stream to create a stream. Note that cons-stream is a special form, because the second operand (naturals (+ n ))) is not evaluated when cons-stream is called. It s only evaluated when cdr-stream is used to inspect the rest of the stream. ˆ nil is the empty stream ˆ cons-stream creates a non-empty stream from an initial element and an expression to compute the rest of the stream ˆ car returns the first element of the stream ˆ cdr-stream computes and returns the rest of stream Streams are very similar to Scheme lists. The cdr of a Scheme list is either another Scheme list or nil; likewise, the cdr-stream of a stream is either a stream or nil. The difference is that the expression for the rest of the stream is computed the first time that cdr-stream is called, instead of when cons-stream is used. Subsequent calls to cdr-stream return this value without recomputing it. This allows us to efficiently work with infinite streams like the naturals example above. We can see this in action by using a non-pure function to compute the rest of the stream: scm> (define (compute-rest n)...> (print 'evaluating!)...> (cons-stream n nil)) compute-rest scm> (define s (cons-stream 0 (compute-rest ))) s scm> (car (cdr-stream s)) evaluating! scm> (car (cdr-stream s)) Note that the symbol evaluating! called. is only printed the first time cdr-stream is Questions 3. What would Scheme display? scm> (define (has-even? s) (cond ((null? s) #f) ((even? (car s)) #t) (else (has-even? (cdr-stream s))))) has-even? scm> (define (f x) (* 3 x)) f scm> (define nums (cons-stream (cons-stream (f 3) (cons-stream (f 5) nil)))) nums

Delayed Expressions 7 scm> nums scm> (cdr nums) scm> (cdr-stream nums) scm> (define (f x) (* x)) f scm> (cdr-stream nums) scm> (has-even? nums) 3. Using streams can be tricky! Compare the following two implementations of filter-stream, the first is a correct implementation whereas the second is wrong in some way. What s wrong with the second implementation? ; Correct (define (filter-stream f s) (cond ((null? s) nil) ((f (car s)) (cons-stream (car s) (filter-stream f (cdr-stream s)))) (else (filter-stream f (cdr-stream s))))) ; Incorrect (define (filter-stream f s) (if (null? s) nil (let ((rest (filter-stream f (cdr-stream s)))) (if (f (car s)) (cons-stream (car s) rest) rest)))) 3.3 Write a function map-stream, which takes a function f and a stream s. It returns a new stream which has all the elements from s, but with f applied to each one. (define (map-stream f s) scm> (define evens (map-stream (lambda (x) (* x )) nat)) evens scm> (car (cdr-stream evens))

8 Delayed Expressions 3.4 Write a function range-stream which takes a start and end, and returns a stream that represents the integers between start and end - (inclusive). (define (range-stream start end) scm> (define s (range-stream 5)) s scm> (car (cdr-stream s)) 3.5 Write a function slice which takes in a stream s, a start, and an end. It should return a Scheme list that contains the elements of s between index start and end, not including end. If the stream ends before end, you can return nil. (define (slice s start end) scm> (slice nat 4 ) (4 5 6 7 8 9 0 ) 3.6 Since streams only evaluate the next element when they are needed, we can combine infinite streams together for interesting results! Use it to define a few of our favorite sequences. We ve defined the function combine-with for you below, as well as an example of how to use it to define the stream of even numbers. (define (combine-with f xs ys) (if (or (null? xs) (null? ys)) nil (cons-stream (f (car xs) (car ys)) (combine-with f (cdr-stream xs) (cdr-stream ys))))) scm> (define evens (combine-with + (naturals 0) (naturals 0))) evens scm> (slice evens 0 0) (0 4 6 8 0 4 6 8) For these questions, you may use the naturals stream in addition to combine-with. (Continued on the next page)

Delayed Expressions 9 i. (define factorials scm> (slice factorials 0 0) ( 6 4 0 70 5040 4030 36880) ii. (define fibs scm> (slice fibs 0 0) (0 3 5 8 3 34) iii. Write exp, which returns a stream where the nth term represents the degree-n polynomial expantion for e x, which is n i=0 xi /i!. You may use factorials in addition to combine-with and naturals in your solution. (define (exp x) scm> (slice (exp ) 0 5) ( 3 5 6.333333333 7 7.66666667)