Recursion. Q: What does this evaluate to? Q: What does this evaluate to? CSE 130 : Programming Languages. Higher-Order Functions

Similar documents
Write: evens. evens [] ====> [] evens [1;2;3;4] ====> [2;4]

CSE 130 [Winter 2014] Programming Languages

Today s Plan. Programming Languages. Example : Factorial. Recursion. CSE 130 : Spring Lecture 6: Higher-Order Functions

Programming Languages. Tail Recursion. CSE 130: Winter Lecture 8: NOT TR. last thing function does is a recursive call

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

Recap: Functions as first-class values

max function Next concat function max function What s the pattern? concat function More on recursion Higher-order functions

Today. Recap from last Week. Factorial. Factorial. How does it execute? How does it execute? More on recursion. Higher-order functions

Factorial. Next. Factorial. How does it execute? Tail recursion. How does it execute? More on recursion. Higher-order functions

Next. Tail Recursion: Factorial. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial.

CSE 130: Programming Languages. Polymorphism. Ranjit Jhala UC San Diego

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Programming Languages

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

Programming Languages

Programming Languages

Programming Languages

CS 340 Spring 2019 Midterm Exam

Programming Languages

FUNCTIONAL PROGRAMMING

Programming Languages

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Programming Languages

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

Haskell: From Basic to Advanced. Part 3 A Deeper Look into Laziness

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

CSCC24 Functional Programming Scheme Part 2

Functional Programming - 2. Higher Order Functions

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Module 8: Local and functional abstraction

Introduction to OCaml

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

Programming Languages. Example 5. Example 4. CSE 130 : Fall type, can reuse code for all types! let rec cat l = match l with

CMSC 330, Fall 2013, Practice Problems 3

Programming Languages

Higher-Order Functions

ML Built-in Functions

Logic - CM0845 Introduction to Haskell

Informatics 1 Functional Programming Lecture 7. Map, filter, fold. Don Sannella University of Edinburgh

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

Exercises on ML. Programming Languages. Chanseok Oh

Programming Languages

CS115 - Module 9 - filter, map, and friends

CMSC 330, Fall 2013, Practice Problem 3 Solutions

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Programming Languages and Techniques (CIS120)

CSCE 314 Programming Languages

Shell CSCE 314 TAMU. Higher Order Functions

Lecture 10 September 11, 2017

CSE341 Autumn 2017, Midterm Examination October 30, 2017

CSci 4223 Principles of Programming Languages

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

CSc 372. Comparative Programming Languages. 11 : Haskell Higher-Order Functions. Department of Computer Science University of Arizona

Functional Programming in C++

CSc 520 Principles of Programming Languages. Currying Revisited... Currying Revisited. 16: Haskell Higher-Order Functions

CSE341 Spring 2016, Midterm Examination April 29, 2016

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Programovací jazyky F# a OCaml. Chapter 5. Hiding recursion using function-as-values

List Functions, and Higher-Order Functions

CIS 120 Midterm I February 16, 2015 SOLUTIONS

Watch out for the arrows. Recollecting Haskell, Part V. A start on higher types: Mapping, 1. A start on higher types: Mapping, 2.

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

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

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

CSE399: Advanced Programming. Handout 2

Topic 5: Examples and higher-order functions

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Programming Languages

Recap: ML s Holy Trinity

CSE341 Spring 2016, Midterm Examination April 29, 2016

CSE 341 : Programming Languages Midterm, Spring 2015

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

MoreIntro_annotated.v. MoreIntro_annotated.v. Printed by Zach Tatlock. Oct 04, 16 21:55 Page 1/10

Australian researchers develop typeface they say can boost memory, that could help students cramming for exams.

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

CSE341, Fall 2011, Midterm Examination October 31, 2011

CS 457/557: Functional Languages

CS 440: Programming Languages and Translators, Spring 2019 Mon

The Haskell HOP: Higher-order Programming

A Programming Language. A different language g is a different vision of life. CSE 130 : Fall Two variables. L1: x++; y--; (y=0)?

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

Forward recursion. CS 321 Programming Languages. Functions calls and the stack. Functions calls and the stack

Introduction to Functional Programming

Lecture 5: Lazy Evaluation and Infinite Data Structures

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

F28PL1 Programming Languages. Lecture 14: Standard ML 4

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

CS1 Recitation. Week 2

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

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

Informatics 1 Functional Programming Lecture 4. Lists and Recursion. Don Sannella University of Edinburgh

Programming Languages

Transcription:

CSE 130 : Programming Languages Higher-Order Functions Ranjit Jhala UC San Diego Recursion A way of life A different way to view computation Solutions for bigger problems From solutions for sub-problems Why know about it? 1. Often far simpler, cleaner than loops But not always 2. Forces you to factor code into reusable units Only way to reuse loop is via cut-paste Q: What does this evaluate to? let rec foo i j = if i >= j then [] else i::(foo (i+1) j) in foo 0 3 (a) [0;1;2] (b) [0;0;0] (c) [] (d) [2;2;2] (e) [2;1;0] Q: What does this evaluate to? let rec range i j = if i >= j then [] else i::(range (i+1) j) range 3 3 ====> [] range 2 3 ====> 2::(range 3 3) ====> 2::[] range 1 3 ====> 1::(range 2 3) ====> 1::2::[] range 0 3 ====> 0::(range 1 3) ====> 0::1::2::[]

Q: What does this evaluate to? Q: What does this evaluate to? let rec range i j = if i >= j then [] else i::(range (i+1) j) Tail Recursive? let range lo hi = let rec helper res j = if lo >= j then res else helper (j::res)(j-1) in helper [] hi Tail Recursive Moral of the day... News PA2 due tomorrow @ 11:59:59 pm Recursion good......but HOFS better PA3 goes up soon Midterm 5/8 In class Open book etc. Practice materials on webpage

Today s Plan A little more practice with recursion Base Pattern -> Base Expression Induction Pattern -> Induction Expression Higher-Order Functions or, why take and return functions? Write: evens (* val evens: int list -> int list *) let rec evens xs = [] ->... x::xs ->... evens [] ====> [] evens [1;2;3;4] ====> [2;4] Write: evens Write: fourletters (* val evens: int list -> int list *) let rec evens xs = x::xs -> if x mod 2 = 0 then x::(evens xs ) else (evens xs ) evens [] ====> [] evens [1;2;3;4] ====> [2;4] (* fourletters: string list -> string list *) let rec fourletters xs = [] ->... x::xs ->... fourletters [] ====> [] fourletters [ cat ; must ; do ; work ] ====> [ must ; work ]

Write: evens (* fourletters: string list -> string list *) let rec fourletters xs = x::xs -> if length x = 4 then x::(fourletters xs ) else (fourletters xs ) fourletters [] ====> [] fourletters [ cat ; must ; do ; work ] ====> [ must ; work ] (* evens: int list -> int list *) let YUCK rec foo xs = x::xs -> if x mod 2 = 0 then x::(foo xs ) else (foo xs ) (* fourletters: string list -> string list *) let rec foo xs = x::xs -> if length x = 4 then x::(foo xs ) else (foo xs ) Yuck Most code is same (* val evens: int list -> int list *) let YUCK rec evens xs = x::xs -> if x mod 2 = 0 then x::(evens xs ) else (evens xs ) (* fourletters: string list -> string list *) let rec fourletters xs = x::xs -> if length x = 4 then x::(fourletters xs ) else (fourletters xs ) Yuck Most code is same Moral of the Day... D.R.Y Don t Repeat Yourself

Moral of the Day... HOFs Allow Factoring General Pattern + Specific Operation let rec evens xs = x::xs -> if x mod 2 = 0 then x::(foo xs ) else (foo xs ) Repetitive Code Begone let rec fourletters xs = x::xs -> if length x = 4 then x::(foo xs ) else (foo xs ) let rec evens xs = YUCK x::xs -> if x mod 2 = 0 then x::(foo xs ) else (foo xs ) letrec fourletters xs = x::xs -> if length x = 4 then x::(foo xs ) else (foo xs ) let rec filter f xs = x::xs -> if f x then x::(filter xs ) else (filter xs ) The filter pattern Factor Into Generic + Specific Specific Operations let evens xs = filter (fun x -> x mod 2 = 0) xs let fourletters xs = filter (fun x -> length x = 4) xs let evens xs = filter (fun x -> x mod 2 = 0) xs let fourletters xs = filter (fun x -> length x = 4) xs let rec filter f xs = x::xs -> if f x then x::(filter xs ) else (filter xs ) The filter pattern let rec filter f xs = x::xs -> if f x then x::(filter xs ) else (filter xs ) Generic filter pattern

Write: listupper (* string list -> string list *) [] ->... x::xs ->... Write: listupper (* string list -> string list *) [] ->[] x::xs ->(uppercase x)::(listupper xs ) listupper [] ====> [] listupper [ carne ; asada ] ====> [ CARNE ; ASADA ] listupper [] ====> [] listupper [ carne ; asada ] ====> [ CARNE ; ASADA ] Write: listsquare Write: listsquare (* int list -> int list *) let rec listsquare xs = [] ->... x::xs ->... (* int list -> int list *) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) listsquare [] ====> [] listsquare [1;2;3;4;5] ====> [1;4;9;16;25] listsquare [] ====> [] listsquare [1;2;3;4;5] ====> [1;4;9;16;25]

Yuck Most code is same What s the Pattern? [] ->[] x::xs ->(uppercase x)::(listupper xs ) [] ->[] x::xs ->(uppercase x)::(listupper xs ) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) What s the Pattern? [] ->[] x::xs ->(uppercase x)::(listupper xs ) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) Refactor Pattern [] ->[] x::xs ->(uppercase x)::(listupper xs ) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) let rec pattern...

Refactor Pattern [] ->[] x::xs ->(uppercase x)::(listupper xs ) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) x::xs -> (f x)::(map f xs ) Refactor Pattern [] ->[] x::xs ->(uppercase x)::(listupper xs ) let listupper = map uppercase x::xs -> (f x)::(map f xs ) Refactor Pattern [] ->[] x::xs ->(uppercase x)::(listupper xs ) let listupper xs = map (fun x -> uppercase x) xs x::xs -> (f x)::(map f xs ) Refactor Pattern let listsquare = map (fun x -> x*x) let rec listsquare xs = x::xs -> (x*x)::(listsquare xs ) x::xs -> (f x)::(map f xs )

Factor Into Generic + Specific Moral of the Day... let listsquare = map (fun x -> x * x) let listupper = map uppercase Specific Op x::xs -> (f x)::(map f xs ) D.R.Y Don t Repeat Yourself Generic iteration pattern Q: What is the type of map? Q: What is the type of map? x::xs -> (f x)::(map f xs ) x::xs -> (f x)::(map f xs ) (a) (`a -> `b) -> `a list -> `b list (b) (int -> int) -> int list -> int list (c) (string -> string) -> string list -> string list (d) (`a -> `a) -> `a list -> `a list (e) (`a -> `b) -> `c list -> `d list (a) (`a -> `b) -> `a list -> `b list Type says it all Apply f to each element in input list Return a list of the results

Q: What does this evaluate to? Don t Repeat Yourself map (fun (x,y) -> x+y) [1;2;3] (a) [2;4;6] (b) [3;5] (c) Syntax Error (e) Type Error x::xs -> (f x)::(map f xs ) Factored code: Reuse iteration template Avoid bugs due to repetition Fix bug in one place Don t Repeat Yourself Recall: len x::xs -> (f x)::(map f xs ) (* a list -> int *) let rec len xs = [] -> 0 x::xs -> 1 + len xs Made Possible by Higher-Order Functions len [] ====> 0 len [ carne ; asada ] ====> 2

Recall: sum Write: concat (* int list -> int *) let rec sum xs = [] -> 0 x::xs -> x + len xs sum [] ====> 0 sum [10;20;30] ====> 60 Write: concat (* string list -> string *) let rec concat xs = [] -> x::xs -> x^(concat xs ) concat [] ====> concat [ carne ; asada ; torta ] ====> carneasadatorta (* string list -> string *) let rec concat xs = [] ->... x::xs ->... concat [] ====> concat [ carne ; asada ; torta ] ====> carneasadatorta What s the Pattern? let rec len xs = [] -> 0 x::xs -> 1 + (len xs ) let rec sum xs = [] -> 0 x::xs -> x + (sum xs ) let rec concat xs = [] -> x::xs -> x^(concat xs )

What s the Pattern? let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) let rec len xs = [] -> 0 x::xs -> 1 + (len xs ) let rec len xs = [] -> 0 x::xs -> 1 + (len xs ) let len = foldr (fun x n -> n+1) 0 let rec sum xs = [] -> 0 x::xs -> x + (sum xs ) let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) let rec sum xs = [] -> 0 x::xs -> x + (sum xs ) let sum = foldr (fun x n -> x+n) 0 let rec concat xs = [] -> x::xs -> x^(concat xs ) let rec concat xs = [] -> x::xs -> x^(concat xs ) let concat = foldr (fun x n -> x^n) fold Pattern let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) Q: What does this evaluate to? let len = foldr (fun x n -> n+1) 0 foldr (fun x n -> x::n) [] [1;2;3] Specific Op let sum = foldr (fun x n -> x+n) 0 let concat = foldr (fun x n -> x^n) let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) (a) [1;2;3] (b) [3;2;1] (c) [] (d) [[3];[2];[1]] (e) [[1];[2];[3]]

fold-right pattern let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) foldr f b [x1;x2;x3] ====> f x1 (foldr f b [x2;x3]) ====> f x1 (f x2 (foldr f b [x3])) ====> f x1 (f x2 (f x3 (foldr f b []))) ====> f x1 (f x2 (f x3 (foldr f b []))) ====> f x1 (f x2 (f x3 (b))) The fold Pattern let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) Tail Recursive? No The fold Pattern let rec foldr f b xs = [] -> b x::xs -> f x (foldr f b xs ) Tail Recursive? Write: concat (TR) let concat xs =... concat [] ====> concat [ carne ; asada ; torta ] ====> carneasadatorta

Write: concat let concat xs = let rec helper res = function [] -> res x::xs -> helper (res^x) xs in helper xs Write: sum (TR) let sum xs =... helper [ carne ; asada ; torta ] ====> helper carne [ asada ; torta ] ====> helper carneasada [ torta ] ====> helper carneasadatorta [] ====> carneasadatorta Write: concat sum [] ====> 0 sum [10;20;30] ====> 60 What s the Pattern? let sum xs = let rec helper res = function [] -> res x::xs -> helper (res+x) xs in helper 0 xs let sum xs = let rec helper res = function [] -> res x::xs -> helper (res + x) xs in helper 0 xs let sum xs = foldl (fun res x -> res + x) 0 let concat xs = let rec helper res = function [] -> res x::xs -> helper (res ^ x) xs in helper xs let sum xs = foldl (fun res x -> res ^ x) helper 0 [10; 100; 1000] ====> helper 10 [100; 1000] ====> helper 110 [1000] ====> helper 1110 [] ====> 1110 let foldl f b xs = let rec helper res = function [] -> res x::xs -> helper (f res x) xs in helper b xs

Accumulation Pattern Q: What does this evaluate to? let foldl f b xs = let rec helper res = function [] -> res x::xs -> helper (f res x) xs in helper b xs foldl (fun res x -> x::res) [] [1;2;3] let sum xs = foldl (fun res x -> res + x) 0 Specific Op let sum xs = foldl (fun res x -> res ^ x) let foldl f b xs = let rec helper res = function [] -> res x::xs -> helper (f res x) xs in helper b xs (a) [1;2;3] (b) [3;2;1] (c) [] (d) [[3];[2];[1]] (e) [[1];[2];[3]] Funcs taking/returning funcs Identify common computation patterns Filter values in a set, list, tree Iterate a function over a set, list, tree map Accumulate some value over a collection fold Pull out (factor) common code: Computation Patterns Re-use in many different situations Another fun function: pipe let pipe x f = f x let ( >) x f = f x Compute the sum of squares of numbers in a list? let sumofsquares xs = xs > map (fun x -> x * x) > foldl (+) 0 Tail Rec?

Funcs taking/returning funcs Identify common computation patterns Filter values in a set, list, tree map Convert a function over a set, list, tree Iterate a function over a set, list, tree fold Accumulate some value over a collection Pull out (factor) common code: Computation Patterns Re-use in many different situations Functions are first-class values Arguments, return values, bindings What are the benefits? Parameterized, similar functions (e.g. Testers) Creating, (Returning) Functions Iterator, Accumul, Reuse computation pattern w/o Using, exposing local info (Taking) Functions Functions are first-class values Arguments, return values, bindings What are the benefits? Parameterized, similar functions (e.g. Testers) Creating, (Returning) Functions Compose Functions: Flexible way to build Complex functions from primitives. Iterator, Accumul, Reuse computation pattern w/o Using, exposing local info (Taking) Functions Funcs taking/returning funcs Higher-order funcs enable modular code Each part only needs local information Data Structure Client Uses list Uses meta-functions: map,fold,filter With locally-dependent funs (lt h), square etc. Without requiring Implement. details of data structure Data Structure Library list Provides meta-functions: map,fold,filter to traverse, accumulate over lists, trees etc. Meta-functions don t need client info (tester? accumulator?)