Top Banner
OCaml Returns Marwan Burelle Basics Mutable Exceptions OCaml Classics EPITA - Practical Programming 02 - Return of the Objective Caml Marwan Burelle [email protected] http://wiki-prog.infoprepa.epita.fr
68

EPITA - Practical Programming 02 - Return of the Objective Caml

Feb 26, 2022

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

EPITA - Practical Programming02 - Return of the Objective Caml

Marwan Burelle

[email protected]://wiki-prog.infoprepa.epita.fr

Page 2: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Outline

1 OCaml BasicsFuntionsPrograms StructureCompiling !

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

3 Exceptions

4 OCaml ClassicsPlay With IntListsBinary Tree

Page 3: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Basics

OCaml Basics

Page 4: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Quick Overview

• OCaml is functional and strongly typed language• It’s a variant of ML and thus provides type inference• It has a well founded semantics• It provides higher-order: function are first-class entity• It provide safe mutability (and thus imperative

features)• It provides an object model• It provides a powerful module sub-language• It can be interpreted (interactively or not), compiled

into bytecode or native code.

Page 5: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

Page 6: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

In The Beginning Was Functions

The most basic expression is functional value

functional value(function x -> x + 1)

Page 7: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Functions Can Be Applied

Applications(function x -> x + 1) 41

Applications can be reduced to closed value (here 42)

Page 8: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Naming

Functional and closed values can be named for latter use

Naming valuelet f = function x -> x + 1 inlet res = f 20 in 2 * res

Naming can be local (as in previous example) or global

Global naminglet f = function x -> x + 1

Page 9: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Function Definitions

Syntax: Function Definitionlet f = function x -> e(* e is an expression where x is free *)

Syntax: Sugarlet f = fun x -> elet f x = e

Syntax: Multiple Parameterslet f = function x -> function y -> x + ylet f = fun x -> fun y -> x + ylet f = fun x y -> x + ylet f x = function y -> x + ylet f x = fun y -> x + ylet f x y = x + y

Page 10: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Curryfied Form

• In OCaml, like in λ−calculus, function always onlyone parameter

• Multiple parameters is obtain by returning a function

Application and Multiple Argumentslet r = (((fun x -> fun y -> x + y) 2) 40)let r’ = (fun x -> fun y -> x + y) 2 40

Page 11: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Examples

Fact !let rec fact n =if n < 2 then 1else n * fact (n-1)

Fact with pattern matchinglet rec fact = function| 0 | 1 -> 1| n -> n * fact (n-1)

Fast Powerlet rec power x = function| 0 -> 1| p ->

(power (x*x) (p/2))* (if p mod 2 = 0 then 1 else x)

Page 12: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

Page 13: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Where Are Double Semi-Colons ?

• Double semi-colons (;;) are useless• Unless: you’re using interactive mode or you’re using

toplevel expressions.• Don’t use double semi-colons !

Double semi-colons are uselesslet f a b = a + blet ref fibo = function| (0 | 1) as n -> n| n -> fibo (n-1) + fibo (n-2)

Page 14: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Code

• Toplevel (outside of any context) phrase must bedefinitions (names, types, modules . . . )

• Avoid toplevel expressions: they are meaningless anderror prone

• It is a good idea to build a main function to clarify theentry-point

A Simple Program(* The main function *)let main () =beginPrintf.printf "Hello World !\n";exit 0

end(* Starting Point *)let _ = main ()

Page 15: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

What’s Wrong With Toplevel Expressions

Interactive Session# 1 + 1;;- : int = 2

But what happen if I do that in a program ?Example:

> cat foo.ml1 + 1;;> ocamlopt -o foo foo.ml> ./foo>

We got a program that seems to do nothing (but it may consumesome cycles for that . . . )

Page 16: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Typical Structures of an OCaml Program

Program Structure(* definitions *)type t = BAD | GOODlet x = 42let f x = x + 1let to_bool = function| BAD -> false| GOOD -> true

(* Entry Point *)let main () =beginPrintf.printf "Hello World !\n";exit 0;

endlet _ = main ()

Page 17: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

Page 18: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Choose Your Kind

• ocamlc: the bytecode compiler:• Bytecode is almost portable• Available on all POSIX system supported by gcc• Offer interesting debugging facilities• Produced code is (very) slow

• ocamlopt: the native compiler:• Produce fast code (from 5 to 15 time faster than

bytecode)• Easier interface with other language• Available only a limited set of architecture (x86, ARM,

Power, SPARC . . . )• Compilation is sometime slower

• ocamlc -cutom: produce a standalone bytecodebased program by combining the VM and thebytecode, you don’t want it.

Page 19: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Basic Compilation

foo.mllet main () =beginPrintf.printf "Hello World !\n";exit 0;

endlet _ = main ()

Example:> lsfoo.ml> ocamlopt -o foo foo.ml> lsfoo foo.cmi foo.cmx foo.ml foo.o> ./fooHello World !>

Page 20: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

The Command Line

cmd.mllet main () =beginArray.iter (Printf.printf "| %S ") Sys.argv;Printf.printf "|\n";exit 0;

endlet _ = main ()

Example:> ocamlopt -o cmd cmd.ml> ./cmd a aa bb "a b c"| "./cmd" | "a" | "aa" | "bb" | "a b c" |>

Page 21: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

ocamlbuild

• ocamlbuild is an automatic build system for OCaml• It’s more effective for multiple files project• For most basic example it can be used without any

configuration

Example:> lsfoo.ml> ocamlbuild foo.nativeFinished, 4 targets (0 cached) in 00:00:00.> ls_build foo.ml foo.native> ./foo.nativeHello World !> ocamlbuild -cleanFinished, 0 targets (0 cached) in 00:00:00.00:00:00 0 (0 ) STARTING> lsfoo.ml

Page 22: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

OCaml And Imperative Programming

OCaml And ImperativeProgramming

Page 23: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Pure Or Not. Pure, That’s The Question !

• Pure Functions are deterministic applications thatmap values (its argument) to a unique result.

• The behavior of a pure function is not affected byelements of the program state outside of its arguments,nor does it affect elements outside of its result.

• Theoretically, any possible behavior can be obtainedwith pure functions, mostly by passing and returningmemory states.

• OCaml choose the pragmatic approach: they breakpurity.

Page 24: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Overview

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

Page 25: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Why Loop Are Not Functional

Example:x = 0;while x < 10 doprint(x);x = x + 1;

done

Can I do that as is in OCaml ?Fail Loop

let x = 0 inwhile x < 10 doPrintf.printf "%d\n" x;(* Now increase x ? *)let x = x + 1 (* OK *)in (* Now what ? *) ()

done

Fail !

Page 26: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Basic For Loop

For the basic cases (bounded iteration) OCaml providessimple for loops without the need of any variables orside-effect operators:

For Loopfor i = 0 to 10 doPrintf.printf "%d\n" i

done

Page 27: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

A Simple Example

Command Line With Looplet main () =beginfor i = 0 to (Array.length Sys.argv) - 1 doPrintf.printf "| %S " Sys.argv.(i)

done;Printf.printf "|\n";exit 0;

endlet _ = main ()

Page 28: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Overview

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

Page 29: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Mutable ?

• Bounded iterations (for loops) aren’t sufficient toexpress all possible all algorithms (but, anyway,recursion is enough.)

• Sometimes we may also want to change the state ofmemory elements.

• But, since we’re using OCaml, we want to keep mostsafety properties of the language.

• Mutable entities should verify the followingproperties to be safe:• Existence: if a symbol exists, it references a valid

memory cell• Initialization: a memory cell always have a defined

value• Stability: the kind of the content of a memory cell

should not change

Page 30: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

References

References are simplest mutable data in OCaml, it’s a kind ofsafe pointer.

references.mllet main () =beginlet r = ref 0 inPrintf.printf "r = ref %d\n" !r;r := 41;Printf.printf "r = ref %d\n" !r;r := !r + 1;Printf.printf "r = ref %d\n" !r;exit 0;

endlet _ = main ()

Page 31: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Some Examples

Basic While Looplet r = ref 0 inwhile !r < 10 doPrintf.printf "%d\n" !r;r := !r + 1;

done

incr and decr(* Already available in Pervasive module *)let incr r = r := !r + 1let decr r = r := !r - 1

Page 32: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Some Examples

Fact !let fact n =if n < 2 then 1elsebeginlet r = ref 1 infor i = n downto 1 dor := !r * i;

done;!r

end

Page 33: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures

closures.mllet f1 = Printf.printf "f1\n"let f2 () = Printf.printf "f2\n"let f3 = fun _ -> Printf.printf "f3\n"let f4 = Printf.printf "f4 (1)\n";fun _ -> Printf.printf "f4 (2)\n"

let main () =Printf.printf "\nMain\n";f1; f2 (); f3 (); f4 (); exit 0

let _ = main ()

Page 34: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures

closures.ml> ./closures.nativef1f4 (1)

Mainf2f3f4 (2)

Page 35: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures And References

next.mllet next =let r = ref 0 infun () ->r := !r + 1;!r

let main () =beginfor i = 1 to 10 doPrintf.printf "%d " (next ())

done;Printf.printf "\n";exit 0;

endlet _ = main ()

Page 36: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures And References

Example:

> ocamlbuild next.nativeFinished, 4 targets (0 cached) in 00:00:00.> ./next.native1 2 3 4 5 6 7 8 9 10>

Page 37: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Arrays And Strings

Arrays and strings are mutable !mutable_array.ml

let main () =let t = Array.make 3 0 inArray.iteri (Printf.printf "t.(%d) = %d ") t;Printf.printf "\n";t.(1) <- 42;Array.iteri (Printf.printf "t.(%d) = %d ") t;Printf.printf "\n";exit 0

let _ = main ()

Example:

> ./mutable_array.nativet.(0) = 0 t.(1) = 0 t.(2) = 0

t.(0) = 0 t.(1) = 42 t.(2) = 0

Page 38: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Arrays And Strings (2)

mutable_strings.mllet main () =beginlet s = "abcd" inPrintf.printf "%S\n" s;s.[3] <- ’e’;Printf.printf "%S\n" s;exit 0;

endlet _ = main ()

Example:

> ocamlbuild mutable_strings.nativeFinished, 4 targets (0 cached) in 00:00:00.> ./mutable_strings.native"abcd""abce"

Page 39: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Records

OCaml provides traditional records. Record’s field can bemarked as mutable.

Example of Recordslet next = let c = ref 0 in fun _ -> incr c;!c

type person = {name : string;uniq_id : int;mutable visit_count : int;

}

let new_person n ={ name=n; uniq_id= next (); visit_count=0 }

let visiting p =p.visit_count <- p.visit_count + 1

Page 40: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

More On Records

Fun With Recordstype state = NIL | MODIFIED | EXCLUSIVE | SHARED | INVALIDtype cache_line = {addr : nativeint;content : nativeint array;mutable cache_state : state;

}

let new_line addr = {addr = addr; cache_state = NIL;content = Array.make 16 (0n);

}

let invalidate addr lines = Array.iter(function| { cache_state = SHARED } as l

when l.addr = addr -> l.cache_state <- INVALID| _ -> ()

) lines

Page 41: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Smart Copy

Smart Record Copytype entity = {id : int;mutable x: float; mutable y: float; mutable z: float;mutable dx: float; mutable dy: float; mutable dz: float;

}

let base_entity = {id = -1;x = 0.; y = 0.; z = 0.;dx = 0.; dy = 0.; dz = 0.;

}

let new_entity ={ base_entity with id = next (); }

Page 42: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Beware When Copying

records.mltype t = {a : int ref;mutable b : int;

}let r = { a = ref 0; b = 0 }let r’ = { r with b = 1; }let main () =beginr.a := 42; r.b <- 42;Printf.printf "r’.a = ref %d\nr’.b = %d\n"!(r’.a) r’.b;

endlet _ = main ()

Example:

> ./records.nativer’.a = ref 42r’.b = 1

Page 43: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Beware When Copying

records.mltype t = {a : int ref;mutable b : int;

}let r = { a = ref 0; b = 0 }let r’ = { r with b = 1; }let main () =beginr.a := 42; r.b <- 42;Printf.printf "r’.a = ref %d\nr’.b = %d\n"!(r’.a) r’.b;

endlet _ = main ()

Example:

> ./records.nativer’.a = ref 42r’.b = 1

Page 44: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Records And References

Interactive Session# ref 0;;- : int ref = {contents = 0}

References are, in fact, syntactic sugar on records.

Theoretical Definitions of type reftype ’a ref = { mutable contents : ’a }

Some consequences

Alternative syntaxlet x = ref 0 inx.contents <- 1; (* same as x := 1 *)(x.contents = !x) (* always true *)

Page 45: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exceptions

Exceptions

Page 46: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exceptions ?

• Exceptions mechanism allows programmer to triggerspecific behavior in some particular cases.

• Exceptions are used to get out of the normal flow ofexecutions: when an exception is raised, the programescapes the current call-stack until the exception iscatched or the program dies.

Page 47: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Declaring Exceptions

• You can define your own exceptions• An exception as the same syntax as data-type tag and

can have parameters• All the exceptions have the exn and can be used as

value.Declaring exception

(* A Simple exception without parameter *)exception MyFstException

(* With two parameters: an int and a string *)exception WrongParameters of int * string

Page 48: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exception: Without Catching

Entry Point

1st Function

2nd Function

3rd Function

exception

Program Boundary

call

call

call

Error: uncaught exception

Page 49: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Raising Exceptions

fail.mlexception MyFailure of int * int

let thrd_fun i j =beginPrintf.printf "3rd function\n%!";ignore (raise (MyFailure(i,j)));Printf.printf "After raise\n%!";

endlet snd_fun i j =Printf.printf "2nd function\n%!";thrd_fun i j

let fst_fun i j =Printf.printf "1st function\n%!";snd_fun i j

let main () =fst_fun 42 666

let _ = main ()

Page 50: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Raising Exceptions

fail.ml> ./fail.native1st function2nd function3rd functionFatal error: exception Fail.MyFailure(42, 666)

Page 51: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Using Predefined Exception

List.assoclet rec assoc x = function| [] -> raise Not_found| (k,v)::_ when x=k -> v| _::t -> assoc x t

failwith and invalid_arglet failwith s = raise (Failure s)let invalid_arg s = raise (Invalid_argument s)

Page 52: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

Entry Point

1st Function

2nd Function

3rd Function

exception

Program Boundary

call

call

call

try … with

Page 53: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

fail2.mlexception MyFailure of int * int

let thrd_fun i j =beginPrintf.printf "3rd function\n%!";ignore (raise (MyFailure(i,j)));Printf.printf "After raise\n%!";

endlet snd_fun i j =Printf.printf "2nd function\n%!";thrd_fun i j

let fst_fun i j =Printf.printf "1st function\n%!";try snd_fun i j with| MyFailure (x,y) ->Printf.eprintf "catched MyFailure (%d,%d)\n%!" x y

let main () =fst_fun 42 666

let _ = main ()

Page 54: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

fail.ml> ./fail2.native1st function2nd function3rd functionFatal error: exception Fail.MyFailure(42, 666)

Page 55: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

OCaml Classics

OCaml Classics

Page 56: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

Page 57: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

fact and fibo(* Factorial (tail recursive) *)let fact n =let rec aux a = function| 0 | 1 -> a| n -> aux (n*a) (n-1)

in aux 1 n

(* Fibonacci (naive version) *)let rec fibo = function| (0|1) as x -> x| n -> fibo (n-1) + fibo (n-2)

Page 58: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Smarter fibo(* Fibonacci (linear-tail recursive version) *)let linear_fibo n =let rec aux f1 f2 x =if x = n then f1else aux (f1 + f2) f1 (x + 1)

inmatch n with| 0 | 1 -> n| _ when n < 0 -> -1| _ -> aux 1 0 1

Page 59: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Power And Square Rootlet rec power x = function| 0 -> 1 | 1 -> x| p -> (power (x*x) (p/2))

* (if p mod 2 = 0 then 1 else x)

let rec numbits a = function| 0 -> a| n -> numbits (a+1) (n lsr 1)

let int_sqrt n =let init = (1 lsl (1+((numbits 0 n)-1)/2)) inlet rec aux x =let y = (x + n/x)/2 inif y >= x then xelse aux y

in aux init

Page 60: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

Page 61: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Length And nth(* List.length *)let length l =let rec aux len = function| [] -> len| a::l -> aux (len + 1) l

in aux 0 l

(* List.nth *)let nth l n =(* Avoid stupid calls *)if n < 0 then invalid_arg "List.nth" elselet rec nth_aux n = function| [] -> failwith "nth"| a::l ->if n = 0 then a else nth_aux (n-1) l

in nth_aux n l

Page 62: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Rev And Append(* List.rev_append *)let rec rev_append l1 l2 =match l1 with| [] -> l2| a :: l -> rev_append l (a :: l2)

(* List.rev *)let rev l = rev_append l [](* List.append or @ *)let append l1 l2 =rev_append (rev l1) l2

(* List.flatten *)let rec flatten = function

[] -> []| l::r -> l @ flatten r

Page 63: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Lists iterators(* List.map *)let rec map f = function| [] -> []| a::l -> let r = f a in r :: map f l

(* List.iter *)let rec iter f = function| [] -> ()| a::l -> f a; iter f l

(* List.rev_map *)let rev_map f l =let rec rmap_f accu = function| [] -> accu| a::l -> rmap_f (f a :: accu) l

inrmap_f [] l

Page 64: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Folds(* List.fold_left *)let rec fold_left f accu l =match l with| [] -> accu| a::l -> fold_left f (f accu a) l

(* List.fold_right *)let rec fold_right f l accu =match l with| [] -> accu| a::l -> f a (fold_right f l accu)

Page 65: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

Page 66: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Binary Treetype ’a tree =| Empty| Node of ’a tree * ’a * ’a tree

(* A size function with all special cases *)let rec size = function| Empty -> 0| Node (Empty, _, Empty) -> 1| Node (child, _, Empty)| Node (Empty, _, child)-> 1 + size child

| Node (left, _, right)-> 1 + size left + size right

Page 67: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Depth First Traversallet rec height = function| Empty -> -1| Node (left, _, right)-> 1 + max (height left) (height right)

let rec prefix accu = function| Empty -> accu| Node (left, k, right)-> k :: prefix (prefix accu right) left

let rec prefix_print print = function| Empty -> ()| Node (left, k, right) ->print k;prefix_print print left;prefix_print print right

Page 68: EPITA - Practical Programming 02 - Return of the Objective Caml

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Breadth First Traversallet breadth_first print t =let q = Queue.create () inbeginif t <> Empty then Queue.push t q;Queue.push Empty q;while not (Queue.is_empty q) domatch Queue.take q with| Empty ->Printf.printf "\n";if not (Queue.is_empty q) thenQueue.push Empty q;

| Node (left,k,right) ->print k;if t <> Empty then Queue.push left q;if t <> Empty then Queue.push right q;

done;end