OCaml Tutorial by Example

By Xah Lee. Date: . Last updated: .

To run ocaml code interactively in the command line, type ocaml in terminal to start.

ocaml in terminal 2016-07-10
ocaml REPL in terminal.

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!";;

There's no line comment such as C's // or bash #.

String

Example of strings:

(* can use \n *)
print_string "Once\n upon a time";;

(* can have lineral linebreak *)
print_string "aa
bb\n";;

(* con contain Unicode *)
print_string "∑ α ≥ ≠ ♥\n";;

(* join strings. Use ^ *)
print_string ("a" ^ "b" ^ "c");;

Numbers

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 automatically convert types. Even simple calculation such as 1 + 1 must have the right types. For example, 1 + 1. is a compiler error, because that's a int and float.

(* 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 *)

Low Line in Numbers 1_000

Number can have low line _ in them, for easy reading.

print_int (3_000 + 10_1);;      (* 3101 *)

The low line can by anywhere between digits.

Function Call Syntax

Parenthesis is never used for function call.

Note: f(x) may work because you are grouping x itself, then the function f will take its value as input.

(* here's a function of 2 parameters *)
let f x y = x + y;;

(* function call *)
f 3 4;;                         (* ⇒ 7 *)

(* do not put paren in function argument *)

(* it's ok to put paren to group the whole function call *)
(f 3 4);;                       (* ⇒ 7 *)

Arithmetics

(* 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";;

You must use the right operator for data of the same type.

(* examples of computing with float type *)

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

(* power 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 *)
"something" ;; (* string *)
true;;             (* bool *)
false;;            (* bool *)
() ;;              (* unit *)

The type “unit” is similar to “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 languages, you have to think about whether 0 or -1 evaluate to true or false, or other special values such as null, empty list, etc. 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 examples 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” expression must be “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 letter or low line _.

module name always starts with a capital letter.

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 *)

The in … is similar to bracket {…} in other langs. Text after the in is a block of code. The use of in can be nested.

(* 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 cannot change.

To have a mutable variable, use the ref keyword in the value. (the “ref” means reference).

(* 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);;