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

Similar documents
Exercises on ML. Programming Languages. Chanseok Oh

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

ML Built-in Functions

Standard ML. Curried Functions. ML Curried Functions.1

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

A quick introduction to SML

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

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

Functions & First Class Function Values

CSE 341 Section 5. Winter 2018

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341, Fall 2011, Midterm Examination October 31, 2011

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

Lecture 12: Data Types (and Some Leftover ML)

CS 440: Programming Languages and Translators, Spring 2019 Mon

Logic - CM0845 Introduction to Haskell

Begin at the beginning

Homework 5. Notes. Turn-In Instructions. Reading. Problems. Handout 19 CSCI 334: Spring (Required) Read Mitchell, Chapters 6 and 7.

Programming Paradigms

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Recap: Functions as first-class values

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

Programming Languages

So what does studying PL buy me?

Programming Languages

Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions

CSCI-GA Scripting Languages

Higher-Order Functions

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Functional Paradigm II

Programming Languages

Functional Programming

Datatype declarations

Formal Semantics. Chapter Twenty-Three Modern Programming Languages, 2nd ed. 1

A general introduction to Functional Programming using Haskell

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

CSE 341: Programming Languages

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

Standard ML. Data types. ML Datatypes.1

SML A F unctional Functional Language Language Lecture 19

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

Introduction to OCaml

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

Any questions. Say hello to OCaml. Say hello to OCaml. Why readability matters. History, Variants. Plan (next 4 weeks)

Functional Programming and Haskell

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

Haskell 98 in short! CPSC 449 Principles of Programming Languages

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

The type checker will complain that the two branches have different types, one is string and the other is int

Programming Languages

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Lecture 4: Higher Order Functions

Programming Languages

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

CS115 - Module 9 - filter, map, and friends

Lists. Michael P. Fourman. February 2, 2010

CSE 130 [Winter 2014] Programming Languages

General Computer Science (CH ) Fall 2016 SML Tutorial: Practice Problems

Generative and accumulative recursion. What is generative recursion? Example revisited: GCD. Readings: Sections 25, 26, 27, 30, 31

Scope. Chapter Ten Modern Programming Languages 1

If we have a call. Now consider fastmap, a version of map that uses futures: Now look at the call. That is, instead of

CSc 372, Spring 1996 Mid-term Examination Solution Key

Programming Languages and Compilers (CS 421)

Higher Order Functions in Haskell

Carlos Varela RPI September 19, Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL

Module 8: Local and functional abstraction

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

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

Functional abstraction

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

An introduction introduction to functional functional programming programming using usin Haskell

Functional Paradigm II

The Environment Model

F28PL1 Programming Languages. Lecture 14: Standard ML 4

Inductive Data Types

CSCE 314 Programming Languages

A Brief Introduction to Standard ML

Introduction to OCaml

Lecture 2: The Basis of SML

Shell CSCE 314 TAMU. Higher Order Functions

The Environment Model. Nate Foster Spring 2018

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

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

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Functional Programming - 2. Higher Order Functions

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

CSE 130 [Winter 2014] Programming Languages

Variables and Bindings

INTRODUCTION TO HASKELL

CSCC24 Functional Programming Typing, Scope, Exceptions ML

Lecture 10 September 11, 2017

CSCC24 Functional Programming Scheme Part 2

Lists. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

CSE 3302 Programming Languages Lecture 8: Functional Programming

Haskell Overview II (2A) Young Won Lim 8/9/16

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Chapter 2 SML, a Functional Programming Language

Transcription:

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

Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order functions Chapter Nine Modern Programming Languages, 2nd ed. 2

More Pattern-Matching Last time we saw pattern-matching in function definitions: fun f 0 = "zero" f _ = "non-zero"; Pattern-matching occurs in several other kinds of ML expressions: case n of 0 => "zero" _ => "non-zero"; Chapter Nine Modern Programming Languages, 2nd ed. 3

Match Syntax A rule is a piece of ML syntax that looks like this: <rule> ::= <pattern> => <expression> A match consists of one or more rules separated by a vertical bar, like this: <match> ::= <rule> <rule> ' ' <match> Each rule in a match must have the same type of expression on the right-hand side A match is not an expression by itself, but forms a part of several kinds of ML expressions Chapter Nine Modern Programming Languages, 2nd ed. 4

Case Expressions - case 1+1 of = 3 => "three" = 2 => "two" = _ => "hmm"; val it = "two" : string The syntax is <case-expr> ::= case <expression> of <match> This is a very powerful case construct unlike many languages, it does more than just compare with constants Chapter Nine Modern Programming Languages, 2nd ed. 5

Example case x of _::_::c::_ => c _::b::_ => b a::_ => a nil => 0 The value of this expression is the third element of the list x, if it has at least three, or the second element if x has only two, or the first element if x has only one, or 0 if x is empty. Chapter Nine Modern Programming Languages, 2nd ed. 6

Generalizes if if exp 1 then exp 2 else exp 3 case exp 1 of true => exp 2 false => exp 3 The two expressions above are equivalent So if-then-else is really just a special case of case Chapter Nine Modern Programming Languages, 2nd ed. 7

Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order functions Chapter Nine Modern Programming Languages, 2nd ed. 8

Predefined Functions When an ML language system starts, there are many predefined variables Some are bound to functions: - ord; val it = fn : char -> int - ~; val it = fn : int -> int Chapter Nine Modern Programming Languages, 2nd ed. 9

Defining Functions We have seen the fun notation for defining new named functions You can also define new names for old functions, using val just as for other kinds of values: - val x = ~; val x = fn : int -> int - x 3; val it = ~3 : int Chapter Nine Modern Programming Languages, 2nd ed. 10

Function Values Functions in ML do not have names Just like other kinds of values, function values may be given one or more names by binding them to variables The fun syntax does two separate things: Creates a new function value Binds that function value to a name Chapter Nine Modern Programming Languages, 2nd ed. 11

Anonymous Functions Named function: - fun f x = x + 2; val f = fn : int -> int - f 1; val it = 3 : int Anonymous function: - fn x => x + 2; val it = fn : int -> int - (fn x => x + 2) 1; val it = 3 : int Chapter Nine Modern Programming Languages, 2nd ed. 12

The fn Syntax Another use of the match syntax <fun-expr> ::= fn <match> Using fn, we get an expression whose value is an (anonymous) function We can define what fun does in terms of val and fn These two definitions have the same effect: fun f x = x + 2 val f = fn x => x + 2 Chapter Nine Modern Programming Languages, 2nd ed. 13

Using Anonymous Functions One simple application: when you need a small function in just one place Without fn: - fun intbefore (a,b) = a < b; val intbefore = fn : int * int -> bool - quicksort ([1,4,3,2,5], intbefore); val it = [1,2,3,4,5] : int list With fn: - quicksort ([1,4,3,2,5], fn (a,b) => a<b); val it = [1,2,3,4,5] : int list - quicksort ([1,4,3,2,5], fn (a,b) => a>b); val it = [5,4,3,2,1] : int list Chapter Nine Modern Programming Languages, 2nd ed. 14

The op keyword - op *; val it = fn : int * int -> int - quicksort ([1,4,3,2,5], op <); val it = [1,2,3,4,5] : int list Binary operators are special functions Sometimes you want to treat them like plain functions: to pass <, for example, as an argument of type int * int -> bool The keyword op before an operator gives you the underlying function Chapter Nine Modern Programming Languages, 2nd ed. 15

Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order functions Chapter Nine Modern Programming Languages, 2nd ed. 16

Higher-order Functions Every function has an order: A function that does not take any functions as parameters, and does not return a function value, has order 1 A function that takes a function as a parameter or returns a function value has order n+1, where n is the order of its highest-order parameter or returned value The quicksort we just saw is a second-order function Chapter Nine Modern Programming Languages, 2nd ed. 17

Practice What is the order of functions with each of the following ML types? int * int -> bool int list * (int * int -> bool) -> int list int -> int -> int (int -> int) * (int -> int) -> (int -> int) int -> bool -> real -> string What can you say about the order of a function with this type? ('a -> 'b) * ('c -> 'a) -> 'c -> 'b Chapter Nine Modern Programming Languages, 2nd ed. 18

Currying We've seen how to get two parameters into a function by passing a 2-tuple: fun f (a,b) = a + b; Another way is to write a function that takes the first argument, and returns another function that takes the second argument: fun g a = fn b => a+b; The general name for this is currying Chapter Nine Modern Programming Languages, 2nd ed. 19

Curried Addition - fun f (a,b) = a+b; val f = fn : int * int -> int - fun g a = fn b => a+b; val g = fn : int -> int -> int - f(2,3); val it = 5 : int - g 2 3; val it = 5 : int Remember that function application is leftassociative So g 2 3 means ((g 2) 3) Chapter Nine Modern Programming Languages, 2nd ed. 20

Advantages No tuples: we get to write g 2 3 instead of f(2,3) But the real advantage: we get to specialize functions for particular initial parameters - val add2 = g 2; val add2 = fn : int -> int - add2 3; val it = 5 : int - add2 10; val it = 12 : int Chapter Nine Modern Programming Languages, 2nd ed. 21

Advantages: Example Like the previous quicksort But now, the comparison function is a first, curried parameter - quicksort (op <) [1,4,3,2,5]; val it = [1,2,3,4,5] : int list - val sortbackward = quicksort (op >); val sortbackward = fn : int list -> int list - sortbackward [1,4,3,2,5]; val it = [5,4,3,2,1] : int list Chapter Nine Modern Programming Languages, 2nd ed. 22

Multiple Curried Parameters Currying generalizes to any number of parameters - fun f (a,b,c) = a+b+c; val f = fn : int * int * int -> int - fun g a = fn b => fn c => a+b+c; val g = fn : int -> int -> int -> int - f (1,2,3); val it = 6 : int - g 1 2 3; val it = 6 : int Chapter Nine Modern Programming Languages, 2nd ed. 23

Notation For Currying There is a much simpler notation for currying (on the next slide) The long notation we have used so far makes the little intermediate anonymous functions explicit fun g a = fn b => fn c => a+b+c; But as long as you understand how it works, the simpler notation is much easier to read and write Chapter Nine Modern Programming Languages, 2nd ed. 24

Easier Notation for Currying Instead of writing: fun f a = fn b => a+b; We can just write: fun f a b = a+b; This generalizes for any number of curried arguments - fun f a b c d = a+b+c+d; val f = fn : int -> int -> int -> int -> int Chapter Nine Modern Programming Languages, 2nd ed. 25

Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order functions Chapter Nine Modern Programming Languages, 2nd ed. 26

Predefined Higher-Order Functions We will use three important predefined higher-order functions: map foldr foldl Actually, foldr and foldl are very similar, as you might guess from the names Chapter Nine Modern Programming Languages, 2nd ed. 27

The map Function Used to apply a function to every element of a list, and collect a list of results - map ~ [1,2,3,4]; val it = [~1,~2,~3,~4] : int list - map (fn x => x+1) [1,2,3,4]; val it = [2,3,4,5] : int list - map (fn x => x mod 2 = 0) [1,2,3,4]; val it = [false,true,false,true] : bool list - map (op +) [(1,2),(3,4),(5,6)]; val it = [3,7,11] : int list Chapter Nine Modern Programming Languages, 2nd ed. 28

The map Function Is Curried - map; val it = fn : ('a -> 'b) -> 'a list -> 'b list - val f = map (op +); val f = fn : (int * int) list -> int list - f [(1,2),(3,4)]; val it = [3,7] : int list Chapter Nine Modern Programming Languages, 2nd ed. 29

The foldr Function Used to combine all the elements of a list For example, to add up all the elements of a list x, we could write foldr (op +) 0 x It takes a function f, a starting value c, and a list x = [x 1,, x n ] and computes: f ( ( ( ( )) )) x, f x2, f xn 1, f xn, c 1 So foldr (op +) 0 [1,2,3,4] evaluates as 1+(2+(3+(4+0)))=10 Chapter Nine Modern Programming Languages, 2nd ed. 30

Examples - foldr (op +) 0 [1,2,3,4]; val it = 10 : int - foldr (op * ) 1 [1,2,3,4]; val it = 24 : int - foldr (op ^) "" ["abc","def","ghi"]; val it = "abcdefghi" : string - foldr (op ::) [5] [1,2,3,4]; val it = [1,2,3,4,5] : int list Chapter Nine Modern Programming Languages, 2nd ed. 31

The foldr Function Is Curried - foldr; val it = fn : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b - foldr (op +); val it = fn : int -> int list -> int - foldr (op +) 0; val it = fn : int list -> int - val addup = foldr (op +) 0; val addup = fn : int list -> int - addup [1,2,3,4,5]; val it = 15 : int Chapter Nine Modern Programming Languages, 2nd ed. 32

The foldl Function Used to combine all the elements of a list Same results as foldr in some cases - foldl (op +) 0 [1,2,3,4]; val it = 10 : int - foldl (op * ) 1 [1,2,3,4]; val it = 24 : int Chapter Nine Modern Programming Languages, 2nd ed. 33

The foldl Function To add up all the elements of a list x, we could write foldl (op +) 0 x It takes a function f, a starting value c, and a list x = [x 1,, x n ] and computes: f ( ( ( ( )) )) x f x, n, n 1 2, 1, f So foldl (op +) 0 [1,2,3,4] evaluates as 4+(3+(2+(1+0)))=10 Remember, foldr did 1+(2+(3+(4+0)))=10 x f x c Chapter Nine Modern Programming Languages, 2nd ed. 34

The foldl Function foldl starts at the left, foldr starts at the right Difference does not matter when the function is associative and commutative, like + and * For other operations, it does matter - foldr (op ^) "" ["abc","def","ghi"]; val it = "abcdefghi" : string - foldl (op ^) "" ["abc","def","ghi"]; val it = "ghidefabc" : string - foldr (op -) 0 [1,2,3,4]; val it = ~2 : int - foldl (op -) 0 [1,2,3,4]; val it = 2 : int Chapter Nine Modern Programming Languages, 2nd ed. 35