Scala Ocaml Cheatsheet#

This page presents a quick reference for various OCaml features as they contrast with Scala. Please see OCaml resources for more detail.

Operators#

Caution

For equality checking use = for equal and <> for not-equals.
Do not use == or != in OCaml unless you have good reason to do so!

Scala

OCaml

==
=
!=
<>

Variables#

Scala

OCaml

val x = e
let x = e
val x = e
x
let x = e in
x
val x: Int = 1
let x: int = 1

Functions#

Scala

OCaml

def f(x: Int): Int = x
let f (x: int): int = x
def add(x: Int, y: Int): Int = x + y
let add (x: int) (y: int): int = x + y
add(2, 3)
add 2 3
(x: Int) => x
fun (x: int) -> x

Recursive functions#

OCaml requires recursive functions be marked with the rec keyword.

Scala

OCaml

def fac(n: Int): Int =
    if (n < 2) 
        1 
    else 
        n * fac(n - 1)
let rec fac (n: int): int =
    if n < 2
    then 1
    else n * fac (n - 1)

For mutually recursive functions we use the and keyword to make a later declared function visible.

Scala

OCaml

def isEven(n: Int): Boolean =
  if (n == 0)
    true
  else
    isOdd(n - 1)

def isOdd(n: Int): Boolean =
  if (n == 0)
    false
  else
    isEven(n - 1)
let rec is_even (n: int): bool =
  if n = 0
  then true
  else is_odd (n - 1)
and is_odd (n: int): bool =
  if n = 0
  then false
  else is_even (n - 1)

Control structures#

Scala

Ocaml

if (test) x else y
if test then x else y
iOpt match {
  case Some(i) => i
  case None    => 0
}
match i_opt with
| Some i -> i
| None   -> 0
while (test) {
  body
}
while test do
  body
done

Data structures#

Tuples#

Scala

Ocaml

(1, 2, 3)
(1, 2, 3)
x._1
fst x
x._2
snd x

List#

Scala

Ocaml

x::Nil
x::[]
List(1, 2, 3)
[1; 2; 3]
def sum(xs: List[Int]): Int = 
  xs.foldLeft(0)((x, acc) => x + acc)
let sum (xs: int list): int = 
  List.fold_left (fun x acc -> x + acc) 0 xs

Option#

Scala

Ocaml

Some(42)
Some 42
None
None

Types#

Scala

OCaml

(Int, Boolean)
int * bool
Int => Boolean
int -> bool
Option[T]
'a option

Operator pitfalls#

Equality operators#

OCaml has operators for both structural equality and physical equality. = is structual equals and <> is structural not-equals. == is physical equals and != is physical not-equals. To illustrate the difference, consider the following example:

# let x = ref 0;;
# let y = ref 0;;
# x = y;;
- : bool = true
# x == y;;
- : bool = false

In this example, x = y evaluates to true because both are references to 0, while x == y evaluates to false since they are not the same references.

Comparison#

Be mindful when you compare elements, as OCaml will infer an ordering on elements of any datatype you declare. This will be the order of declaration. As an example, consider the following:

# type ex = C | B | A;;
type ex = C | B | A
# C < A;;
- : bool = true
# C < B;;
- : bool = true
# A < B;;
- : bool = false

Mutability#

In Scala we can declare mutable variables with the var keyword. Instead of mutable variables OCaml has mutable references. These represent a reference to a location in memory similar to a pointer in C. To create a reference cell in OCaml we can use ref:

# let x = ref 0;;
val x : int ref = {contents = 0}

Note the type int ref, indicating a reference to a cell containing an integer. To read from and write to the memory location, we can use ! (dereference) and := (assignment).

# !x;;
- : int = 0
# x := 1;;
- : unit = ()
# !x;;
- : int = 1

If we have two references two the same memory cell, changes will be reflected:

# let y = x;;
val y : int ref = {contents = 1}
# !y;;
- : int = 1
# x := 0;;
- : unit = ()
# !y;;
- : int = 0

Finally, consider the following examples of an imperative factorial function:

Scala

OCaml

def fac(n: Int): Int = {
  var acc = 1
  var res = 1
  while (acc <= n) {
    res = res * acc
    acc = acc + 1
  }
  res
}
let fac (n: int): int =
  let acc = ref 1 in
  let res = ref 1 in
  while !acc <= n do
    res := !res * !acc;
    acc := !acc + 1
  done;
  !res