18
Writing functions in ML

Writing functions in ML

Embed Size (px)

DESCRIPTION

Writing functions in ML. Defining a simple function. MLWorks> fun add (x, y) = x + y; val add : (int * int) -> int = fn Notice what this says: add is a value the type of add is (int * int) -> int the -> denotes a function Therefore, a function is a kind of value! - PowerPoint PPT Presentation

Citation preview

Page 1: Writing functions in ML

Writing functions in ML

Page 2: Writing functions in ML

Defining a simple function

• MLWorks> fun add (x, y) = x + y;– val add : (int * int) -> int = fn

• Notice what this says:– add is a value– the type of add is (int * int) -> int – the -> denotes a function– Therefore, a function is a kind of value!– The actual value is abbreviated to fn

Page 3: Writing functions in ML

Another function definition

• MLWorks> fun double x = 2 * x;– val double : int -> int = fn

• Why don't we need parentheses around the parameter x?

• Every function in ML takes one parameter and returns one result.– The parameter may be a tuple– The result may be a tuple

Page 4: Writing functions in ML

add again

• MLWorks> fun add (x, y) = x + y;– val add : (int * int) -> int = fn

• MLWorks> add (7, 3);– val it : int = 10

• MLWorks> add(3.0, 5.0);– Gives a type error; why?– ML is strongly typed, but it can deduce types– If expression could be real or int, default is int

Page 5: Writing functions in ML

Statements in ML

• There are no statements in ML– ML is a purely functional language; it has no

side effects*...but ML does have expressions

• Every expression has a value

* Except for output "statements"--we won't be doing output

Page 6: Writing functions in ML

The if...then...else expression

• if boolean-expression then expression1 else expression2

• The else part is required (why?)– because the if expression must have a value

• expression1 and expression2 must have the same type– because ML is strongly typed– it needs to know the type of the expression

Page 7: Writing functions in ML

Using if...then...else

• MLWorks> fun max(x, y) = if x > y then x else y;– val max : (int * int) -> int = fn

• MLWorks> max (7, 5);– val it : int = 7

Page 8: Writing functions in ML

Integer division, with remainder

• MLWorks> fun divide(x, y) = (x div y, x mod y);– val divide : (int * int) -> (int * int) = fn

• MLWorks> divide (20, 3);– val it : (int * int) = (6, 2)

• We aren't returning two results, just one--but it's a tuple

• Similarly, we're only providing one parameter

Page 9: Writing functions in ML

Adding vectors

• MLWorks> fun addVec ((x1, y1), (x2, y2)) = ((x1 + x2), (y1 + y2));– val addVec : ((int * int) * (int * int)) -> (int

* int) = fn

• MLWorks> addVec ((3, 5), (10, 20));– val it : (int * int) = (13, 25)

Page 10: Writing functions in ML

LISP-like operations

• Recall that ML has the following operations:– hd returns the head of a list

– tl returns the tail of a list

– :: adds an element to a list

• These are essentially the same as CAR, CDR, and CONS in LISP

• Can we define CAR, CDR, and CONS in ML?

Page 11: Writing functions in ML

Redefining LISP

• MLWorks> fun car x = hd x;– val car : 'a list -> 'a = fn

• MLWorks> fun cdr x = tl x;– val cdr : 'a list -> 'a list = fn

• MLWorks> fun cons (x, y) = x :: y;– val cons : ('a * 'a list) -> 'a list = fn

• MLWorks> car (cdr [1,2,3,4]);– val it : int = 2

Page 12: Writing functions in ML

Testing our LISP functions

• MLWorks> cons([1,2], [3,4]);– Function applied to argument of wrong type

Near: cons (1 :: 2 :: nil, 3 :: 4 :: nil) Required argument type: (int list * int list list) Actual argument type: (int list * int list) Type clash between int and int list

• Elements of list must be same type!• There is no solution (with the ML we know so far)

Page 13: Writing functions in ML

Trapped in time

• MLWorks> val age = 20;• MLWorks> fun older ( ) = age + 1;• MLWorks> older ( );

– val it : int = 21

• MLWorks> val age = 35;• MLWorks> older ( );

– val it : int = 21

Page 14: Writing functions in ML

ML adds to state, doesn't change it

• ML has no "assignment"

• val age = 21; associates age with 21• This age is then used in function older• val age = 35; associates a new age with

35• The old age goes out of scope

• ...but older still refers to the old one

Page 15: Writing functions in ML

Functions are values, too

• MLWorks> fun f x = 2 * x;• MLWorks> fun g x = f (f x);• MLWorks> g 5;

– val it : int = 20

• MLWorks> fun f x = 3 * x;• MLWorks> g 5;

– val it : int = 20

Page 16: Writing functions in ML

Debugging functions

• You saw that redefining a function does not affect prior uses of that function

• Therefore, you can't change a function by changing something it calls

• Everything should work OK if you compile all your functions from a file every time

• Sometimes you just have to restart ML

Page 17: Writing functions in ML

It's all in the binding times

• ML's approach seems strange, but you have seen it before

• x = 5;y = 2 * x;x = x + 1;print "y = ", y;

• Would you expect y = 12 to be printed?

• Remember, functions are values too!

Page 18: Writing functions in ML

The End