OCaml Tutorial by Example

By Xah Lee. Date:

To run ocaml code, you can run it interactively in the command line. To start command line, type “ocaml”. You can also run it from a file. Suppose “mytest.ml” is your ocaml source file. Run it like this: ocaml mytest.ml.

Comments and Printing

(* comment. *)
(* comment can be (* nested *).*)

print_int 3;;
print_string "\n";;
print_float 3.0;;
print_string "\n";;
print_string "good!";;

Strings and Numbers

Example of strings:

print_string "Once upon a time …\n";;

(* Unicode ok, linebreak ok, “\n” ok *)
print_string "α β λ
≤ ≥ ≠ ⊂ ℚ ℝ ℂ ∑ ↔ ⇔ ◀▶▲▼\n";;

(* joining strings. Use “^” *)
print_string ("Once upon a time … " ^ "There was …");;

There are 2 built-in type for numbers: “int” and “float”. For example, -2, 3 are type int. Float are basically numbers with decimals. For example: 3., 0. are type float.

Ocaml does not mix types or automatically convert types. Even simple calculation such as 1 + 1 must have the right types. For example, 1 + 1. is a compiler error. You must use the right operator for data of the same type.

(* example of printing different types of values *)
print_int (3 + 4);; (* integer *)
print_string "\n";;
print_float (2. +. 7.);; (* float. *)
(* The “+.” is for adding number of float type *)

Arithmetics

Parenthesis is never used for function call such as f(3). Note: f(3) will work however because you are grouping 3 itself, then the function f will take its value as input.

(* examples of simple arithmetic with int type. *)

print_int (3 + 4);;
(* paren is needed, because if not, print_int will take 3 as its only
argument, which returns a null value of “unit” type, and unit + 4 will
result error because type mismatch. *)

print_string "\n";;

print_int ((3 + 4 - 5) / 2 );;
print_string "\n";;

print_int (3 * 4 - 5);;
print_string "\n";;
(* examples of computing with float type *)

(* you need to use -. +. *. /. etc for float type. *)
print_float (3. *. 4. -. 5.);;
print_string "\n";;

(* exponential operator is “**”, and it acts on float types. *)
print_float (3. ** 2.);;        (* prints 9 *)

(* There's no “**.” *)

Types

Ocaml has these built-in simple types: int, float, bool, char, string, unit.

(* example of values having built-in types *)

3 ;;    (* int *)
3. ;;   (* float *)
'x' ;;  (* char *)
"war and peace" ;; (* string *)
true;;             (* bool *)
false;;            (* bool *)
() ;;              (* unit *)

The type “unit” is similar to a “void”, “undefined”, “nil” in other languages. It is represented by the syntax (). For example, the return value of the print_string function is “unit”.

To convert a value's type, use one of the type converting functions:

(int_of_float 3.) + 1 ;; (* change float to int, then add 1 *)

(float_of_int 3) +. 2.2;; (* change int to float, then add a float. *)

print_string (string_of_float 3.2);; (* change float to string *)

print_string "\n";;

print_string (string_of_int 3);; (* change int to string *)

True and False

true and false are literals of type “bool” (“bool” means boolean). In most other lang, you have to think about whether 0 or -1 evaluate to true or false, or other special things like nil, null, undefined function, empty string, empty list, etc. Because Ocaml is strict on type, you don't have these issues, because you can't use anything that's not a boolean type in a place that expects boolean. If you do, it is a compiler error.

Here are some example of boolean expressions:

Printf.printf "%B" (3 < 4);;            (* prints true *)

Printf.printf "%B" (true && false);;    (* prints false *)

Printf.printf "%B" (true || (3 < 4));;    (* prints true *)

If Then Else

let x = 5;;
if x == 3 then print_string "yay\n" else print_string "nay\n";;
if x >= 3 then print_string "yay\n";;

Expressions for “then” and “else” MUST match type.

If you do not use “else”, then the value of the “then” section must be the “unit” type.

(* example of nested “if then” *)
let x = 5;;
let y = 3;;

print_string
(if x == 5 then
   (if y == 3 then "y is 3" else "y is not 3")
 else "x ≠ n");;
(* indentation doesn't matter *)

“If then else” is a expression. It returns a value.

let x = if true then 4 else 9;;         (* x is now 4 *)

Variables

Variables MUST start with lower case.

Example of global variables:

let b = 4;;
let b = 5;;
print_int b;; (* now b is 5 *)

Local variables are defined using the form:

let varname = value in body

The “body” is any expression. In the body, any varname will be replaced by its value.

let b = 4 in 2 + b;; (* b is 4 here *)

print_int b;; (* b is undefined here *)

Basically, the in … acts like a bracket “{…}” in other langs. Text after the “in” is a block of code. The use of “in” can be nested. Example:

(* nesting of local variable blocks *)
let b = 4 in
let b = b + 1 in
  b;;  (* ⇒ 5 *)

(* can also be written like this: *)
let b = 4 in let b = b + 1 in b;;       (* ⇒ 5 *)
(* tab and return chars in source code have no special meaning *)

Indentation does not have special meaning in Ocaml.

Mutable Variables

The let x = 4 in … construct is actually like defining a constant. The variable is set to a value and is not allowed to be reset to something else. To have a mutable variable, use the “ref” keyword in the value. (the “ref” means reference). Example:

(* declare x to be a mutable variable of type “int ref” *)
let x = ref 3;;

(* reset the value of x *)
x := 4;;

(* syntax for getting the value of x *)
!x;;

x := !x + 1;;  (* increase x by 1 *)

print_int !x;;

List, Array, Tuple, Records

OCaml Tutorial: List, Array, Tuple

Function

OCaml Tutorial: Function

Loading File and Module

If you have a source file “x.ml”, you can load it, like this:

#use "xx.ml";;                          (* loading a file *)

(* all functions in the file will be usable here *)
print_int (f 3);;