CS 61A Higher Order Functions and Recursion Fall 2018 Discussion 2: June 26, Higher Order Functions. HOFs in Environment Diagrams

Similar documents
CS 61A Higher Order Functions and Recursion Fall 2018 Discussion 2: June 26, 2018 Solutions. 1 Higher Order Functions. HOFs in Environment Diagrams

ENVIRONMENT DIAGRAMS AND RECURSION 2

Environment Diagrams and Recursion Fall 2017 Discussion 2: September 6, 2017 Solutions. 1 More Environment Diagrams

HIGHER ORDER FUNCTIONS AND ENVIRONMENT DIAGRAMS 2

ENVIRONMENT DIAGRAMS AND RECURSION 2

RECURSION: n. SEE RECURSION 3

HIGHER-ORDER FUNCTIONS 2

CONTROL AND HIGHER ORDER FUNCTIONS 1

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

CS 61A Control and Environments Spring 2018 Discussion 1: January 24, Control. If statements. Boolean Operators

RECURSION 3. 1 Recursion COMPUTER SCIENCE 61A. June 30, 2016

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

C ONTROL AND H IGHER O RDER F UNCTIONS

RECURSION, RECURSION, (TREE) RECURSION! 2

CONTROL AND ENVIRONMENTS 1

CONTROL AND HIGHER ORDER FUNCTIONS 2

RECURSION, RECURSION, (TREE) RECURSION! 3

ITERATION AND RECURSION 3

RECURSION 7. 1 Recursion COMPUTER SCIENCE 61A. October 15, 2012

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

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

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

RECURSION, RECURSION, (TREE) RECURSION! 3

CONTROL AND HIGHER ORDER FUNCTIONS 1

functional programming in Python, part 2

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

CS2500 Exam 2 Fall 2011

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

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))

DRAWING ENVIRONMENT DIAGRAMS

Structure and Interpretation of Computer Programs Fall 2015 Midterm 1

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

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

Understanding Recursion

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

Programming Languages

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

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

Structure and Interpretation of Computer Programs

Compiler Construction Lecture 05 A Simple Stack Machine. Lent Term, Lecturer: Timothy G. Griffin. Computer Laboratory University of Cambridge

Lecture #3: Environments

University of Massachusetts Lowell

Module 10: Imperative Programming, Modularization, and The Future

Lecture #5: Higher-Order Functions. A Simple Recursion. Avoiding Recalculation. Redundant Calculation. Tail Recursion and Repetition

Midterm Review. CS61A Summer Katya Stukalova Jerome Baek

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

SCHEME AND CALCULATOR 5b

Sample Final Exam Questions

CS1 Lecture 15 Feb. 19, 2018

Excerpt from "Art of Problem Solving Volume 1: the Basics" 2014 AoPS Inc.

James G. Looby Hudson Valley Community College

EXAM PREPARATION SECTION 1

April 2 to April 4, 2018

Encodings. Using the minimal λ-calculus language we get. functions. local binding. booleans. numbers... and recursive functions?

Discussion 4. Data Abstraction and Sequences

CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Whereweare. CS-XXX: Graduate Programming Languages. Lecture 7 Lambda Calculus. Adding data structures. Data + Code. What about functions

Structure and Interpretation of Computer Programs

Structure and Interpretation of Computer Programs

CS 61A HKN Review Session. Nathan Zhang, Caleb Wyllie

Box-and-arrow Diagrams

n! = 1 * 2 * 3 * 4 * * (n-1) * n

Organization of Programming Languages CS3200/5200N. Lecture 11

ECE 2400 Computer Systems Programming Fall 2018 Topic 2: C Recursion

CS422 - Programming Language Design

CS3 Midterm 2 Standards and Solutions

RECURSION AND LINKED LISTS 3

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

CS152: Programming Languages. Lecture 7 Lambda Calculus. Dan Grossman Spring 2011

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

CS61A Notes 02b Fake Plastic Trees. 2. (cons ((1 a) (2 o)) (3 g)) 3. (list ((1 a) (2 o)) (3 g)) 4. (append ((1 a) (2 o)) (3 g))

CS3: Introduction to Symbolic Programming. Lecture 10: Tic-tac-toe Lambda.

Implementing Recursion

TAIL RECURSION, SCOPE, AND PROJECT 4 11

This exam has 10 pages including the title page. Please check to make sure all pages are included.

Typing Control. Chapter Conditionals

An introduction to Scheme

Homework 3: Recursion Due: 11:59 PM, Sep 25, 2018

Project 5 - The Meta-Circular Evaluator

1.7 Limit of a Function

Structure and Interpretation of Computer Programs

Chapter 15 Functional Programming Languages

Introduction to Scheme

6.00 Notes On Big-O Notation

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Structure and Interpretation of Computer Programs

INTERPRETERS AND TAIL CALLS 9

Homework 6: Higher-Order Procedures Due: 11:59 PM, Oct 16, 2018

Introduction to Scientific Computing

Local defini1ons. Func1on mul1ples- of

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

DM536 / DM550 Part 1 Introduction to Programming. Peter Schneider-Kamp.

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Halting Measures and Termination Arguments

Reading 8 : Recursion

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

CS115 - Module 9 - filter, map, and friends

The Beauty and Joy of Computing 1 Lab Exercise 9: Problem self-similarity and recursion - Python version

Project 5 - The Meta-Circular Evaluator

def F a c t o r i a l ( n ) : i f n == 1 : return 1 else : return n F a c t o r i a l ( n 1) def main ( ) : print ( F a c t o r i a l ( 4 ) )

Transcription:

CS 61A Higher Order Functions and Recursion Fall 2018 Discussion 2: June 26, 2018 1 Higher Order Functions HOFs in Environment Diagrams Recall that an environment diagram keeps track of all the variables that have been defined and the values they are bound to. However, values are not necessarily only integers and strings. Environment diagrams can model more complex programs that utilize higher order functions. def add_num(x): return lambda y: x + y add_two = add_num(2) add_two(3) Lambdas are represented similiarly to functions in environment diagrams, but since they lack instrinsic names, the lambda symbol (λ) is used instead. The parent of any function (including lambdas) is always the frame in which the function is defined. It is useful to include the parent in environment diagrams in order to find variables that are not defined in the current frame. In the previous example, when we call add two (which is really the lambda function), we need to know what x is in order to compute x + y. Since x is not in the frame f2, we look at the frame s parent, which is f1. There, we find x is bound to 2. As illustrated above, higher order functions that return a function have their return value represented with a pointer to the function object.

2 Higher Order Functions and Recursion A Note on Lambda Expressions A lambda expression evaluates to a function, called a lambda function. In the code above, lambda y: x + y is a lambda expression, and can be read as a function that takes in one parameter y and returns x + y. A lambda expression by itself evaluates to a function but does not bind it to a name. Also note that the return expression of this function is not evaluated until the lambda is called. This is similar to how defining a new function using a def statement does not execute the functions body until it is later called. >>> what = lambda x : x + 5 >>> what <function <lambda> at 0xf3f490> Unlike def statements, lambda expressions can be used as an operator or an operand to a call expression. This is because they are simply one-line expressions that evaluate to functions. >>> (lambda y: y + 5)(4) 9 >>> (lambda f, x: f(x))(lambda y: y + 1, 10) 11

Higher Order Functions and Recursion 3 Questions 1.1 Draw the environment diagram that results from executing the code below. 1 def curry2(h): 2 def f(x): 3 def g(y): 4 return h(x, y) 5 return g 6 return f 7 make_adder = curry2(lambda x, y: x + y) 8 add_three = make_adder(3) 9 add_four = make_adder(4) 10 five = add_three(2)

4 Higher Order Functions and Recursion 1.2 Write curry2 as a lambda function 1.3 Draw the environment diagram that results from executing the code below. 1 n = 7 2 3 def f(x): 4 n = 8 5 return x + 1 6 7 def g(x): 8 n = 9 9 def h(): 10 return x + 1 11 return h 12 13 def f(f, x): 14 return f(x + n) 15 16 f = f(g, n) 17 g = (lambda y: y())(f)

Higher Order Functions and Recursion 5 1.4 The following question is extremely difficult. Something like this would not appear on the exam. Nonetheless, it s a fun problem to try. Draw the environment diagram that results from executing the code below. Note that using the + operator with two strings results in the second string being appended to the first. For example "C" + "S" concatenates the two strings into one string "CS" 1 y = "y" 2 h = y 3 def y(y): 4 h = "h" 5 if y == h: 6 return y + "i" 7 y = lambda y: y(h) 8 return lambda h: y(h) 9 y = y(y)(y)

6 Higher Order Functions and Recursion Writing Higher Order Functions 1.5 Write a function that takes in a function cond and a number n and prints numbers from 1 to n where calling cond on that number returns True. def keep_ints(cond, n): Print out all integers 1..i..n where cond(i) is true >>> def is_even(x):... # Even numbers have remainder 0 when divided by 2.... return x % 2 == 0 >>> keep_ints(is_even, 5) 2 4 1.6 Write a function similar to keep_ints like before, but now it takes in a number n and returns a function that has one parameter cond. The returned function prints out numbers from 1 to n where calling cond on that number returns True. def keep_ints(n): Returns a function which takes one parameter cond and prints out all integers 1..i..n where calling cond(i) returns True. >>> def is_even(x):... # Even numbers have remainder 0 when divided by 2.... return x % 2 == 0 >>> keep_ints(5)(is_even) 2 4

Higher Order Functions and Recursion 7 2 Recursion A recursive function is a function that is defined in terms of itself. A good example is the factorial function. Although we haven t finished defining factorial, we are still able to call it since the function body is not evaluated until the function is called. Note that when n is 0 or 1, we just return 1. This is known as the base case, and it prevents the function from infinitely recursing. Now we can compute factorial(2) in terms of factorial(1), and factorial(3) in terms of factorial(2), and factorial(4) well, you get the idea. def factorial(n): if n == 0 or n == 1: return 1 else: return n * factorial(n-1) There are three common steps in a recursive definition: 1. Figure out your base case: The base case is usually the simplest input possible to the function. For example, factorial(0) is 1 by definition. You can also think of a base case as a stopping condition for the recursion. If you can t figure this out right away, move on to the recursive case and try to figure out the point at which we can t reduce the problem any further. 2. Make a recursive call with a simpler argument: Simplify your problem, and assume that a recursive call for this new problem will simply work. This is called the leap of faith. For factorial, we reduce the problem by calling factorial(n-1). 3. Use your recursive call to solve the full problem: Remember that we are assuming the recursive call works. With the result of the recursive call, how can you solve the original problem you were asked? For factorial, we just multiply (n 1)! by n. Note: One way to go understand recursion is to separate out two things: internal correctness and not running forever (known as halting ). A recursive function is internally correct if it is always does the right thing assuming that every recursive call does the right thing. For example, the same factorial function from above but with no base case is internally correct, but does not halt. A recursive function is correct if and only if it is both internally correct and halts; but you can check each property separately. The recursive leap of faith is temporarily placing yourself in a mindset where you only check internal correctness.

8 Higher Order Functions and Recursion Questions 2.1 Write a function that takes two numbers m and n and returns their product. Assume m and n are positive integers. Use recursion, not mul or *! Hint: 5*3 = 5 + 5*2 = 5 + 5 + 5*1. For the base case, what is the simplest possible input for multiply? For the recursive case, what does calling multiply(m - 1, n) do? What does calling multiply(m, n - 1) do? Do we prefer one over the other? def multiply(m, n): >>> multiply(5, 3) 15

Higher Order Functions and Recursion 9 2.2 Write a recursive function that takes in an integer n and prints out a countdown from n to 1. First, think about a base case for the countdown function. simplest input the problem could be given? What is the After you ve thought of a base case, think about a recursive call with a smaller argument that approches the base case. What happens if you call countdown(n - 1)? Then, put the base case and the recursive call together, and think about where a print statement would be needed. def countdown(n): >>> countdown(3) 3 2 1 2.3 How can we change countdown to count up instead without modifying a lot of the code?

10 Higher Order Functions and Recursion 2.4 Write a recursive function that takes a number n and returns the sum of every other digit, starting from the rightmost digit. Assume n is non-negative. You might find the operators // and % useful. def sum_every_other_digit(n): >>> sum_every_other_digit(7) 7 >>> sum_every_other_digit(30) 0 >>> sum_every_other_digit(228) 10 >>> sum_every_other_digit(123456) 12 >>> sum_every_other_digit(1234567) # 1 + 3 + 5 + 7 16

Higher Order Functions and Recursion 11 2.5 Draw an environment diagram for the following code: def rec(x, y): if y > 0: return x * rec(x, y - 1) return 1 rec(3, 2) Bonus question: what does this function do?