# Writing functions in OCaml. Defining a simple function # let add (x, y) = x + y;; val add : int * int -> int = Notice what this says: –add is a value.

## Presentation on theme: "Writing functions in OCaml. Defining a simple function # let add (x, y) = x + y;; val add : int * int -> int = Notice what this says: –add is a value."— Presentation transcript:

Writing functions in OCaml

Defining a simple function # let add (x, y) = x + y;; val add : int * int -> int = 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

Another function definition # let double x = x + x;; val double : int -> int = Why don't we need parentheses around the parameter x ? Every function in OCaml takes one parameter and returns one result. –The parameter may be a tuple –The result may be a tuple

add again # let add (x, y) = x + y;; val add : int * int -> int = # add (7, 3);; - : int = 10 # add (3.0, 5.0);; Characters 5-13: This expression has type float * float but is here used with type int * int OCaml is strongly typed, but it can deduce types

Statements in OCaml There are no statements in OCaml OCaml is (almost) a purely functional language; it has no side effects* –but OCaml does have expressions Every expression has a value * Except for output "statements"--we won't be doing output

The if...then...else expression if boolean-expression then expression 1 else expression 2 The else part is required (why?) –because the if expression must have a value expression 1 and expression 2 must have the same type –because OCaml is strongly typed –it needs to know the type of the expression

Using if...then...else # let max (x, y) = if x > y then x else y;; val max : 'a * 'a -> 'a = # max (7, 5);; - : int = 7 # max (7.0, 5.0);; - : float = 7.000000 max, as defined here, is a polymorphic function

Integer division, with remainder # let divide (x, y) = x / y, x mod y;; val divide : int * int -> int * int = # divide (20, 3);; - : int * int = 6, 2 We aren't returning two results, just one--but it's a tuple Similarly, we're only providing one parameter

Adding vectors # let addVec ((x1, y1), (x2, y2)) = (x1 + x2, y1 + y2);; val addVec : (int * int) * (int * int) -> int * int = # addVec ((3, 5), (10, 20));; - : int * int = 13, 25 Notice that parentheses are sometimes necessary

LISP-like operations Recall that OCaml 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 OCaml?

Redefining LISP # let car x = List.hd x;; val car : 'a list -> 'a = # let cdr x = List.tl x;; val cdr : 'a list -> 'a list = # let cons (x, y) = x :: y;; val cons : 'a * 'a list -> 'a list = # car (cdr [1; 2; 3; 4]);; - : int = 2

Testing our LISP functions cons ([1; 2], [3; 4]);; # Characters 6-20: This expression has type int list * int list but is here used with type int list * int list list Elements of list must be same type! There is no solution (with the OCaml we know so far)

Trapped in time # let age = 20;; val age : int = 20 # let older () = age + 1;; val older : unit -> int = # older ();; - : int = 21 # let age = 35;; val age : int = 35 # older ();; - : int = 21

OCaml adds to state, doesn't change it OCaml has no "assignment" let age = 21; associates age with 21 This age is then used in function older let age = 35; associates a new age with 35 The old age goes out of scope, but it doesn't go away (it's lifetime is not over) older still uses the original variable

Functions are values, too # let f x = 2 * x;; val f : int -> int = # let g x = f (f x);; val g : int -> int = # g 5;; - : int = 20 # let f x = 3 * x;; val f : int -> int = # g 5;; - : int = 20

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 OCaml

It's all in the binding times OCaml'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!

The End

Similar presentations