Caml is a dialect of the ML programming language family, developed in France at INRIA. OCaml is the main implementation of the programming language Caml. The features of ML include:
- First-class functions
- Functions can be data, too: parameters and return values
- Favor immutability (“assign once”)
- Data types and pattern matching
- Convenient for certain kinds of data structures
- Type inference
- No need to write types in the source language
- But the language is statically typed
- Supports parametric polymorphism
- Generics in Java, templates in C++
- Exceptions
- Garbage collection
### Working with OCaml
- OCaml programs can be compiled using ocamlc
- Produces .cmo (“compiled object”) and .cmi (“compiled interface”) files
- Use -o to set output file name
- Use -c to compile only to .cmo/.cmi and not to link
- Can also compile with ocamlopt
- Produces .cmx files, which contain native code
- Faster, but not platform-independent (or as easily debugged)
hello.ml:
(* A small OCaml program *)
print_string "Hello world!\n";;
To compile and run
ocamlc hello.ml
./a.out
Hello world!
### Working with multiple files
main.ml
let main () =
print_int (Util.add 10 20);
print_string "\n"
let () = main ()
util.ml
let add x y = x+y
Compile and run:
ocamlc util.ml main.ml
Or compile separately
ocamlc –c util.ml
ocamlc util.cmo main.ml
To execute
./a.out
Use ocamlbuild to compile larger projects and automatically. OCamlbuild finds dependencies. To build a bytecode executable out of main.ml and its local dependencies
ocamlbuild main.byte
The executable main.byte is in _build folder. To execute:
./main.byte
OCaml topleve, a REPL for OCaml
ocaml
OCaml version 4.04.0
# print_string ”Hello world!\n";;
Hello world!
- : unit = ()
To load a file into top level:
#use “filename.ml”
To exit the top-level, type ^D (Control D) or call the exit 0
# exit 0;;
### First OCaml Example
(* A small OCaml program (* with nested comments *) *)
let x = 37;;
let y = x + 5;;
print_int y;;
print_string "\n";;
OCaml is strictly typed
print_int 10;;
10- : unit = ()
Following expressions do not type check
print_int 10.5;;
Error: This expression has type float but an expression was expected of type int
1 + 0.5;;
Error: This expression has type float but an expression was expected of type int
print_int "This function expected an int";;
Error: This expression has type string but an expression was expected of type int
1 + true;;
Error: This expression has type bool but an expression was expected of type int
### if statement
if e1 then e2 else e3
Type checking rules
- if e1 : bool and e2 : t and e3 : t then
- if e1 then e2 else e3 : t
Examples:
if 7 > 42 then "hello" else "goodbye";;
- : string = "goodbye"
if 7 > 42 then "hello" else 10;;
Error: This expression has type int but an expression was expected of type string
An expression is a value
print_int (if 10>5 then 100 else 200);;
100- : unit = ()
### Functions
We use let to define a function:
Factorial function:
let rec fact n =
if n = 0 then
1
else
n * fact (n-1);;
Next integer
let next x = x + 1;;
Swapping two values
let swap (x,y) = (y,x);;
Adding two integers
let add x y = x + y;;
Comparing other types
let eq (x,y) = x = y;; (* = is polymorphic *)
### Function types:
-> (arraow) is the function type constructor
let next x = x + 1;;
val next : int -> int =
let fn x = (int_of_float x) * 3;;
val fn : float -> int =
fact;;
- : int -> int =
### Calling Functions
let rec fact n =
if n = 0 then
1
else
n * fact (n-1)
fact 2
if 2=0 then 1 else 2*fact(2-1)
2 * fact 1
2 * (if 1=0 then 1 else 1*fact(1-1))
2 * 1 * fact 0
2 * 1 * (if 0=0 then 1 else 0*fact(0-1))
2 * 1 * 1
2
### Type annotations
let (x : int) = 3;;
val x : int = 3
let fn (x:int):float = (float_of_int x) *. 3.14;;
val fn : int -> float =
### List
An OCaml list is an immutable, finite sequence of elements of the same type. List is a primitive data type
[1;2;3];;
Nested lists
[ [1;2]; [3;4] ]
empty list
[];;
What are the types of the above lists?
[1;2;3];;
- : int list = [1; 2; 3]
[ [1;2]; [3;4] ];;
- : int list list = [[1; 2]; [3; 4]]
[];;
- : 'a list = []
### Constructing lists
OCaml lists can be constructed using :: notation.
3 :: [];;
- : int list = [3]
2 :: (3 :: []);;
- : int list = [2; 3]
1::2::3::[];;
- : int list = [1; 2; 3]
### Type checking rules
if e1 : t and e2 : t list then e1::e2 : t list
Example:
let x = [1;2;3];;
let y = 4 :: x;;
val y : int list = [4; 1; 2; 3]
let y = x :: 4;; (* does not work; "A :: B" means that B should be a list containing whatever type A is *)
More list type practice
[[[]; []; [1.3;2.4]]];;
- : float list list list = [[[]; []; [1.3; 2.4]]]
[1; 2; "lists must be homogeneous"];;
Error: This expression has type string but an expression was expected of type
int
[1, 2, 3];; (* probably not what you expect; this list has _one_ element *)
(int * int * int) list = [(1, 2, 3)]
[1, 2, 3] is same as [(1,2,3)], a list of 3-tuple with type (int \* int \* int).
[1;2] :: 3 (* expects a list on the right of :: *)
Error: This expression has type int but an expression was expected of type
int list list
Web Accessibility