Variables

All about Variables in Ocaml


Let Binding

In Ocaml, almost everything is an expression. All values are expressions, but not all expressions are values.

The only thing that is not an expression is the let binding:

let x = 5 in
let y = x + 2 in 
print_int y

You can also create functions using let:

let expression:
let square x = 
	let y = x * x in 
	y + 1

Values

A value is an expression that cannot be evaluated further. Values include integers, booleans, strings, lists, and functions. For example:

let x = 10  (* x is bound to the value 10 *)
let is_true = true  (* is_true is bound to the value true *)
let name = "OCaml"  (* name is bound to the string "OCaml" *)

Values are the final result of evaluating expressions. Once a value is produced, it cannot be reduced further.

Expressions

An expression is any code that can be evaluated to produce a value. i.e function applications and conditionals:

let sum = 2 + 3  (* 2 + 3 is an expression that evaluates to the value 5 *)
let result = if sum > 4 then true else false  (* A conditional expression *)

Expressions can also include function calls:

let square x = x * x
square 4  (* -> 16 *)

Immutability

In OCaml, once a value is bound to a variable (using let), it cannot be changed. Essential for functional programming to avoid side effects.

let x = 10
x = 15  (* Error *)

Shadowing

OCaml allows for shadowing, meaning you can reuse variable names, but each let creates a new scope:

let x = 10 in
let x = x + 5 in  (* Shadows the previous value of x *)
print_int x  (* Prints 15 *)

Aliasing

Aliasing occurs when two different variables point to the same mutable data structure (like references or mutable records). Be mindful of this when working with mutable data because modifying the data through one alias will affect the other.

let x = ref 0
let y = x  (* Both x and y refer to the same memory location *)
x := 5  (* Modifying x also modifies y *)
print_int !y  (* Prints 5 *)

References (Mutable Variables)

While OCaml emphasizes immutability, you can create mutable variables using references. This allows you to change the value stored in a variable:

let x = ref 10  (* x is a reference to a mutable value *)
x := 20  (* Change the value of x to 20 *)
print_int !x  (* Prints 20 *)

Global Scope and Local Scope

Variables in OCaml can be defined in either a global or local scope. Global variables are available throughout the program, while local variables exist only within a specific block or function.

let global_var = 100  (* Global variable *)
 
let sum x y =
  let local_var = 10  (* Local variable *)
  x + y + local_var  (* Accessible only inside this function *)

Destructive Update

While OCaml values are immutable, when using mutable data structures like records or arrays, you can perform destructive updates. This allows you to modify the value in place, but only in mutable fields:

type person = { name : string; mutable age : int }
let p = { name = "Alice"; age = 20 }
p.age <- 21  (* Modify the age field in place *)