Introduce syntactic sugar for references
Mutable variable
let mut x = ... in
f x;
x <- ...;
gets translated to
let x = { contents = ... } in
f x.contents;
x.contents <- ...;
Extension to function parameter
let f (mut x:int) =
x <- ...
gets translated to
let f (x:int) =
let x = { contents = x } in
x.contents <- ...
Extension to pattern matching
match e with
| (x, mut y) -> x + y
end
gets translated to
match e with
| (x, y) -> let y = { contents = y } in x + y.contents
end
Type annotations
They apply to the content of the variable:
let mut x:t = ...
gets translated to
let x : ref t = { contents = ... }
Reference passing
Function parameters can be annotated with ref
to denote that they can accept a mutable variable as ref
:
let incr (ref x) = x <- x + 1
let f () = let mut x = 0 in incr x
gets translated to
let incr (x: ref ...) = x.contents <- x.contents + 1
let f () = let x = ref 0 in incr x
Note that it can also accept a plain ref
:
let f () = let x = ref 0 in incr x
gets translated as is.
Note that the extension to pattern matching makes it possible to alias a reference:
let ref x = e in x
gets translated to
let x = e in x.contents
Escaping the automatic dereferencing
Reciprocally, a function that expects a ref
can be given a mutable variable by using the as ref
construct:
let g (x: ref ...) = ...
let f () = let mut x = 0 in g (x as ref)