defining functions
play

Defining Functions Functions in SML Amtoft from Hatcliff Defining - PowerPoint PPT Presentation

Defining Functions Functions in SML Amtoft from Hatcliff Defining values of simple types from Leavens val i = 3; Defining Functions val i = 3 : i n t Functions as Values Multiple Arguments Defining function values: Currying


  1. Defining Functions Functions in SML Amtoft from Hatcliff Defining values of simple types from Leavens − val i = 3; Defining Functions val i = 3 : i n t Functions as Values Multiple Arguments Defining function values: Currying − val i n c = fn ( x ) = > x + 1; Polymorphism val i n c = fn : i n t − > i n t − i n c ( 3 ) ; val i t = 4 : i n t − val i s 3 = fn x = > i f x = 3 then ” yes ” else ”no” ; i s 3 = fn : i n t − > s t r i n g val − i s 3 4; i t = ”no” : s t r i n g val Function types: fn: < domain type > -> < range type >

  2. Fun with fun Functions in SML Amtoft from Hatcliff from Leavens Defining Functions The previous definitions can be abbreviated: Functions as Values Multiple Arguments fun < identifier > ( < parameter list > ) = < expression > ; Currying Polymorphism − fun i n c ( x ) = x + 1; i n c = fn : i n t − > i n t val − fun i s 3 x = x = 3 then ” yes ” else ”no” ; i f val i s 3 = fn : i n t − > s t r i n g − fun t e s t ( x , y ) = i f x < y then y else x+1; val t e s t = fn : i n t ∗ i n t − > i n t

  3. ML Programs Functions in SML Amtoft from Hatcliff from Leavens A (simple) ML program is generally a sequence of function definitions Defining Functions Functions as Values fun push ( value , stack ) Multiple Arguments . . . Currying . . . ; Polymorphism fun pop ( stack ) . . . . . . ; fun empty ( stack ) . . . . . . ; fun make − stack ( value ) . . . . . . ;

  4. Functions as Values Functions in SML Amtoft from Hatcliff from Leavens Functions can be anonymous Defining Functions Functions as Values − fn x = > x + 2; i t = fn : i n t − > i n t Multiple Arguments val Currying Functions can be tuple components Polymorphism − val p = ( fn ( x , y ) = > x + y , ( x , y ) = > x − y ) ; fn val p = ( fn , fn ) : ( i n t ∗ i n t − > i n t ) ∗ ( i n t ∗ i n t − > i n t ) − #1(p ) ( 2 , 3 ) ; val i t = 5 : i n t − #2(p ) ( 2 , 3 ) ; val i t = ˜1 : i n t

  5. Functions as Values Functions in SML Amtoft from Hatcliff from Leavens Functions can be list elements Defining Functions − fun add1 ( x ) = x + 1; Functions as Values val add1 = fn : i n t − > i n t Multiple Arguments − fun add2 ( x ) = x + 2; Currying add2 = fn : i n t − > i n t val Polymorphism − fun add3 ( x ) = x + 3; add3 = fn : i n t − > i n t val − val l s = [ add1 , add2 , add3 ] ; l s = [ fn , fn , fn ] : ( i n t − > i n t ) l i s t val − hd ( l s ) ( 3 ) ; i t = 4 : i n t val − hd ( t l ( l s ) ) ( 3 ) ; val i t = 5 : i n t

  6. Higher-Order Functions Functions in SML Amtoft from Hatcliff Functions can be given as arguments from Leavens − fun do fun ( f , x ) = f ( x ) + x + 1; Defining Functions val do fun = fn : ( i n t − > i n t ) ∗ i n t − > i n t Functions as Values Multiple Arguments − do fun ( add2 , 3 ) ; Currying val i t = 9 : i n t Polymorphism − do fun ( add3 , 5 ) ; val i t = 14 : i n t Functions can be returned as results − fun make addx ( x ) = fn ( y ) = > y + x ; make addx = fn : i n t − > i n t − > i n t val − val add5 = make addx ( 5 ) ; val add5 = fn : i n t − > i n t − add5 ( 3 ) ; val i t = 8 : i n t

  7. Functions Are Values Functions in SML Amtoft from Hatcliff from Leavens A higher-order function Defining Functions ◮ “processes” other functions Functions as Values Multiple Arguments ◮ takes a function as input, and/or Currying returns a function as a result Polymorphism In SML, functions are first-class citizens Just like any other value: they can be ◮ placed in tuples ◮ placed in lists ◮ passed as function arguments ◮ returned as function results

  8. Compare with C Functions in SML Amtoft from Hatcliff from Leavens We must use function pointers (and it’s ugly): Defining Functions #include < s t d i o . h > Functions as Values Multiple Arguments int add3 ( int x ) Currying { Polymorphism return x + 3; } int do fun ( int ( ∗ fp )( int x ) , int y ) { ( ∗ fp )( y ) + y + 1; return } void main ( void ) { p r i n t f ( ”%d \ n” , do fun ( add3 , 5 ) ) ; }

  9. Compare with Pascal Functions in SML Amtoft from Hatcliff from Leavens A little better, but we can’t return functions as a result. Defining Functions function add3 ( x : integer ) : integer ; Functions as Values Multiple Arguments begin Currying add3 := x + 3; Polymorphism end ; function do fun ( f ( x : integer ) : integer ; y : integer ) : integer ; begin do fun := f ( y ) + y + 1; end ; begin writeln ( do fun ( add3 , 5 ) ) ; end .

  10. Scope of Variables Functions in SML Amtoft from Hatcliff from Leavens − val a = 2; val a = 2 : i n t Defining Functions − fun myfun x = x + a ; Functions as Values val myfun = fn : i n t − > i n t Multiple Arguments − val a = 4; Currying Polymorphism val a = 4 : i n t − myfun ( 5 ) ; ??? val i t = 7 : i n t ◮ Declarations at the top-level may seem like assignments.... but they’re not! ◮ Technically speaking, ML is statically scoped ◮ New definitions of the same variable don’t overwrite old definitions; they shadow the old definitions ◮ For efficiency, old definitions may be garbage collected if they are not referred to.

  11. Multiple Argument Functions Functions in SML Amtoft from Hatcliff from Leavens Defining Functions Functions as Values ◮ In reality, each SML function takes exactly one Multiple Arguments Currying argument and returns one result value. Polymorphism ◮ If we need to pass multiple arguments, we generally package the arguments up in a tuple. − fun add3 ( x , y , z ) = x + y + z ; val add3 = fn : i n t ∗ i n t ∗ i n t − > i n t ◮ If a function takes n argument, we say that it has arity n .

  12. Multiple Argument Functions Functions in SML Amtoft from Hatcliff Can we implement “multiple argument functions” from Leavens without tuples or lists? Defining Functions ◮ Yes, use higher-order functions Functions as Values − fun add3 ( x ) = Multiple Arguments fn ( y ) = > fn ( z ) = > x + y + z ; Currying val add3 = fn : i n t − > i n t − > i n t − > i n t Polymorphism − (( add3 ( 1 ) ) ( 2 ) ) ( 3 ) ; val i t = 6 : i n t − add3 1 2 3; ( ∗ omit n e e d l e s s parens ∗ ) i t = 6 : i n t val Abbreviate definition − fun add3 x y z = x + y + z ; add3 = fn : i n t − > i n t − > i n t − > i n t val − add3 1 2 3; i t = 6 : i n t val

  13. Interpreting Function Types Functions in SML Amtoft from Hatcliff from Leavens Look closely at types: Defining Functions Functions as Values 1 . fn : int − > int − > int − > int Multiple Arguments abbreviates Currying 2 . fn : int − > ( int − > ( int − > int )) Polymorphism which is different from 3 . fn : ( int − > int ) − > ( int − > int ) ◮ The first two types describes a function that ◮ takes an integer as an argument and returns a function of type int − > int − > int as a result. ◮ The last type describes a function that ◮ takes a function of type int − > int as argument and returns a function of type int − > int .

  14. Currying Functions in SML Amtoft from Hatcliff from Leavens The function Defining Functions − fun add3 ( x ) = Functions as Values ( y ) = ( z ) = > x + y + z ; fn > fn Multiple Arguments add3 = fn : i n t − > i n t − > i n t − > i n t val Currying is called the “curried” version of Polymorphism − fun add3 ( x , y , z ) = x + y + z ; val add3 = fn : i n t ∗ i n t ∗ i n t − > i n t History: ◮ The process of moving from the first version to the second is called “currying” after the logician Haskell Curry who supposedly first identified the technique. ◮ The technique actually goes back to another logician named Sch¨ onfinkel ◮ but we still call it “currying” (thank goodness!).

  15. Instantiating Curried Functions Functions in SML Amtoft from Hatcliff from Leavens Defining Functions Curried functions are useful because they allow us to create Functions as Values partially instantiated or specialized functions where some (but Multiple Arguments not all) arguments are supplied. Currying − fun add x y = x + y ; Polymorphism val add = fn : i n t − > i n t − > i n t − val add3 = add 3; val add3 = fn : i n t − > i n t − val add5 = add 5; val add5 = fn : i n t − > i n t − add3 2 + add5 6; val i t = 16 : i n t

  16. Polymorphic Functions Functions in SML Amtoft from Hatcliff from Leavens Defining Functions The theory of polymorphism underlying SML is an Functions as Values elegant feature that clearly distinguishes SML from other Multiple Arguments languages that are less well-designed. Currying Polymorphism − fun id x = x ; val id = fn : ’ a − > ’ a − id 5; val i t = 5 : i n t − id ”abc” ; val i t = ”abc” : s t r i n g − id ( fn x = > x + x ) ; val i t = fn : i n t − > i n t − id (2) + f l o o r ( id ( 3 . 5 ) ) ; val i t = 5 : i n t Polymorphism: (poly = many, morph = form)

Recommend


More recommend