OCaml Introduction
by "Blag" - Developer Evangelist
What is OCaml?
OCaml is a Multi-Paradigm, Imperative, Functional and Object-Oriented programming language.
OCaml is free and Open Source.
If you have used Haskell or Erlang before...you should be fine with OCaml.
How to install OCaml?
Of course...the best option is to use Linux
apt-get install ocaml
On Mac's shouldn't be that hard either...
brew install ocaml
On Windows...well...I haven't tried it out...Windows's OCaml
Who uses OCaml?
- Facebook -> Hack, a compiler for a variant of PHP. Flow, Static type checking for JavaScript. Pfff, Set of tools for code analysis, visualizations, and style-preserving source transformation.
- Bloomberg -> Advanced financial derivatives risk management application.
- Citrix -> XenServer, a world-class virtualization system.
- American Museum of Natural History -> Sotware package POY for Phylogenetic inference.
- Jane Street -> They use OCaml for everything, from research infrastructure to trading systems to operations and accounting systems.
Starting out...
Once OCaml is installed, we can simply call it from the terminal

Package Management
OCaml uses OPAM which is pretty easy to use...
opam list -a --> will list all installed packages
opam install bitcoin --> will install an interface to the official BitCoin API
opam update --> will update the source list
opam upgrade --> will upgrade the installed packages
utop and Core
utop is a better interactive shell for OCaml...
Core is a library that brings more power to OCaml development
opam install core utop

Once utop is up and running...
type open Core.Std
This will save us some time and also will remove the need to specify functions by their classes...
Variables
Like every functional language...variables are immutable...but using "Let" we can assing them new values...
let myVar = 5;;
val myVar : int = 5
let myVar = "Hello OCaml";;
val myVar : string = "Hello OCaml"
Just keep in mind that this will work only in the interactive shell...
Strings in OCaml are really a list of characters.
So we can easily access each value...
let myVar = "Hello OCaml";;
val myVar : string = "Hello OCaml"
myVar.[0];;
- : char = H
myVar.[6];;
- : char = O
Variable can change their values after assignment...but that's not a good functional practice
Best thing is to update the value when calling a function...
Its value doesn't really change but it's carried out by the function...
Tuples
Sometimes we need to group values together...for that, we can use Tuples.
Tuples can have any number of values...
let myvar = (1,"Blag");;
val myvar : int * string = (1, "Blag")
let myvar = (1,"Blag","SAP");;
val myvar : int * string * string = (1, "Blag", "SAP")
We can extract the Tuples values using fst and snd.
let myvar = (1,"Blag");;
val myvar : int * string = (1, "Blag")
fst myvar;;
- : int = 1
snd myvar
"Blag"
- : string = "Blag"
When using tuples with more than 2 values...we need to create a function...we'll see that later...
List
Lists are the most common and used variable type in OCaml.
Lists comes with some nice built-in functions...
let someNumbers = [1;2;3;4;5];;
val someNumbers : int list = [1; 2; 3; 4; 5]
let someNames = ["Blag","Schmerdy","Rocky"];;
val someNames : string list = ["Blag"; "Schmerdy"; "Rocky"]
let someNumbers = [1,2,3,4,5];;
val someNumbers : int list = [1; 2; 3; 4; 5]
List.hd_exn someNumbers;;
- : int = 1
List.hd_exn someNumbers;;
- : int list = [2; 3; 4; 5]
List.last_exn someNumbers;;
- : int = 5
List.take someNumbers 3;;
- : int list = [1; 2; 3]
let hello = "Hello";;
val hello : string = "Hello"
hello.[0]
- : char = H
String.sub hello 0 2;;
- : string = "He"
List.nth_exn [1;2;3;4;5] 0;;
- : int = 1
List.append [1;2;3] [4;5;6]
- : int list = [1; 2; 3; 4; 5; 6]
"Hello " ^ "World!"
- : string = "Hello World!"
1 :: [2;3;4;5]
- : int list = [1; 2; 3; 4; 5]
Functions
Function are very important...
Using Pattern Matching we can call the same function and it will perform different actions...
First Application
For our First Application we need to wrote the code on any editor. We need to use the .ml extension
After compilation, an executable will be generated...
On Geany we need to press the button Compile the current file...and then Run or view the current file
On the terminal do corebuild "name_of_file".native
For this example...we don't need to compile it...just call it as an include...
Call your file "triples.ml" (all in lowercase).
open Core.Std
let first myTuple =
let (x,_,_) = myTuple in
printf "%d" x
let second myTuple =
let (_,x,_) = myTuple in
printf "%s" x
let third myTuple =
let (_,_,x) = myTuple in
printf "%s" x
When we run it we're going to see...

Second Application
In this example we're going to use Pattern Matching
Call your file "greetings.hs" (all in lowercase).
Again...there's no need to compile this code...but to include it...
open Core.Std
let greet gender name =
match gender with
| "male" -> "Good Morning Mr. " ^ name
| "female" -> "Good Morning Mrs. " ^ name
| _ -> "Good Morning ??? " ^ name
When we run it we're going to see...

List Higher-Order functions
Unlike other Functional languages...OCaml doesn't provide List Comprehensions.
But the same can be achieved by using Higher-Order functions with Lambda functions...
List.map (List.range 1 6) (fun x -> x * 10);;
- : int list = [10; 20; 30; 40; 50]
List.filter (List.map (List.range 1 11) (fun x -> x * 10))
(fun x -> if x > 50 then true else false);;
- : int list = [60; 70; 80; 90; 100]
let doubleIt x = x * 2;;
val doubleIt : int -> int = <fun>
List.map [1;2;3;4;5] (doubleIt);;
- : int list = [2; 4; 6; 8; 10]
Recursion
Recursion is one of the key points in OCaml...you call a function that calls itself multiple times.
As we can't change the value of a variable, we can pass different values as parameters. This way we can update the variable value without changing the variable value...
Third Application
In this example we're going to create a Fibonacci sequence generator...
Call your file "fibonacci.ml" (all in lowercase).
We will compile this code...
open Core.Std
let rec fib num a b =
match num with
| num when a > 0 && num > 1 ->
string_of_int (a + b) ^ " " ^
fib (num - 1) (a+b) a
| num when a = 0 ->
string_of_int a ^ " " ^
string_of_int b ^ " " ^
string_of_int (a + b) ^ " " ^
fib (num - 1) (a+b) b
| num -> ""
let () =
print_string "Enter a number: "
let num = read_int() in
printf "%s" (fib num 0 1)
When we run it we're going to see...

Fourth Application
In this example we're going to create an LED Number
Call your file "LED_Numbers.ml" (all in lowercase).
open Core.Std
let get_leds number =
let leds = [0, [" _ ";"| | ";"|_| "];
1, [" ";"| ";"| "];
2, [" _ ";" _| ";"|_ "];
3, ["_ ";"_| ";"_| "];
4, [" ";"|_| ";" | "];
5, [" _ ";"|_ ";" _| "];
6, [" _ ";"|_ ";"|_| "];
7, ["_ ";" | ";" | "];
8, [" _ ";"|_| ";"|_| "];
9, [" _ ";"|_| ";" _| "]] in
for i = 0 to 2 do
for j = 0 to
String.length(number) - 1 do
let line = List.Assoc.find_exn leds
(int_of_string(Char.to_string(
number.[j]))) in
printf "%s" (List.nth_exn line i)
done;
print_string "\n"
done
let () =
print_string "Enter a number: "
let num = read_line() in
get_leds num
When we run it we're going to see...

Fifth Application
In this example we're going to create a Decimals to Romans application
Call your file "DecToRomans.ml" (all in lowercase).
open Core.Std
let rec show_romans num ctr =
let romans = [(1000,"M");(900,"CM");(500,"D");
(90,"XC");(50,"L");(40,"XL");
(10,"X");(9,"IX");(5,"V");
(4,"IV");(1,"I")] in
let roman = List.nth_exn romans ctr in
if num > fst roman then
snd roman ^ show_romans (num - fst roman) ctr
else if num < fst roman && num > 0 then
show_romans num (ctr + 1)
else "" ^ snd roman
let () =
print_string "Enter a number: "
let num = read_int() in
printf "%s\n" (show_romans num 0)
When we run it we're going to see...

Sixth Application
In this example we're going to read a file and count how many time a letter appears...
Call your file "countletters.ml" (all in lowercase).
Create a file called "readme.txt" with the following text...
"This is a text file that we're going to read it using OCaml"
open Core.Std
let rec update_list lst_count lst_file i top =
if i < top then
let file_value = List.nth_exn lst_file i in
let value = try List.Assoc.find_exn
lst_count (file_value) + 1
with Not_found -> 1 in
let lst_count = List.Assoc.add
lst_count (file_value) (value) in
update_list lst_count lst_file (i+1) top
else
for i = 0 to List.length lst_count - 1 do
let lst_value = List.nth_exn lst_count i in
printf "%c-->%d\n"
(fst lst_value) (snd lst_value)
done
let () =
let file = input_line ( open_in "readme.txt") in
let lst_file = String.to_list file in
let lst_count = [] in
update_list lst_count lst_file 0
(List.length lst_file - 1)
When we run it we're going to see...

That's it for now...
I hope you had some fun...
Functional languages are very important
because they force you think differently...
and getting the grasp of OCaml is not an easy thing...
Contact Information
Blag --> blag@blagarts.com
@Blag on Twitter