Mutability
From Textbook: Mutability
Refs¶
Syntax¶
ref x
!x
x := eref x: creates a reference using therefkeyword (let x = ref 0creates a location in memory whose contents are initialized to0)!x: dereferencesxand returns the contents of the memory locationx := e: is an assignment. It mutates the contentsxto be1. Note thatxitself still points to the same location (i.e., address) in memory. Variables really are immutable in that way. What changes is the contents of that memory location. Memory is mutable; variable bindings are not.
Counter¶
let next_val =
let counter = ref 0
in fun () ->
incr counter;
!counter
let next_val_broken = fun () ->
let counter = ref 0
in incr counter;
!counter
next_val_broken () = 1 ... 1 ... 1
next_val () = 1 ... 2 ... 3 ...Look at how these two functions’ results differ. In the first example, counter is just a temporary variable later bound to the fun() -> ... Therefore, counter will not be initiated every time we call next_val . It is evaluated only when the first time it is defined.
Sequencing¶
e1; e2; ... ; enThe sentence above evaluates each one of ei in order from left to right, returning only vn.
If the values
viprevious expressioneievaluates to are not of type unit, the compiler will give you a warning because it makes no sense to throw away those values. To get rid of the warning (if you’re sure that’s what you need to do), there’s a functionignore : 'a -> unitin the standard library. Using it,ignore(2+3); 7will compile without a warning. Of course, you could code upignoreyourself:let ignore _ = ().
This is a syntactic sugar of let _ = e1 in e2
Equality¶
- Physical Equality (
==,!=): same address - Structural Equality (
=,<>): same content
Mutable Fields (in Record)¶
Syntax¶
(* declare a record with mutable field *)
type point = {x:int; y:int; mutable c:string}
let p = {x=0; y=0; c="red"}
(*mutate the field of that record*)
p.c <- "white"
p.x <- 3
# Error: The record field x is not mutableMutable Stack¶
Arrays and Loops¶
Arrays¶
- Array creation:
[|e0; e1; ...; en|] - Array indexing:
e1.(e2) - Array assignment:
e1.(e2) <- e3
Loops¶
while e1 do e2 done
let i = ref 0
while !i<=2 do print_endline(string_of_int v.(!i)); incr i done
for x=e1 to e2 do e3 done
for x=e1 downto e2 do e3 done
for i=1 to 2 do print_endline(string_of_int v.(i)) done
for i=2 downto 0 do print_endline(string_of_int v.(i)) donewhileloops terminate whene1becomes falseforloops execute once for each integer frome1toe2for..toloops evaluate starting ate1and incrementingxeach iteration;for..downtoloops evaluate starting ate1and decrementingxeach iteration