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