# OCaml and Value Semantics
## Locality: Performance
```neovim {"update":true,"path":"_/code/1721240954095.ml","timestamp":1725485334036}
<pre>
<span class="Comment"><span class="-spell">(* Locality - can a variable escape it's region *)</span></span>
<span class="-keyword">let</span> <span class="-variable"><span class="-function">add_stuff</span></span> <span class="-variable">x</span> <span class="Delimiter">=</span>
<span class="Comment"><span class="-spell">(* With `locals`, y does not get allocated on the heap.
Instead it goes to a special data stack *)</span></span>
<span class="-keyword">let</span> <span class="-variable">y</span> <span class="Delimiter">=</span> <span class="-number">1</span> <span class="-keyword">in</span>
<span class="-variable">x</span> <span class="Operator">+</span> <span class="-variable">y</span>
</pre>
```
^1721240954095
In this example, `y` would not be added to the heap as a variable that needs to be garbage collected later. Instead it would be added to the data stack (name?) and automatically freed when the function exits without interacting with the garbage collector at all.
OCaml has a generational garbage collector. This means OCaml has two "pools" of memory, short-term memory and long-term memory.
The short-term memory (due to a bunch of stuff I don't wanna type right now) is basically a stack of values that gets pushed on top of and then when it's full the garbage collector checks to see what's still alive and moves those to long-term memory. This is really good for functional languages in particular because you tend to make lots of short-lived variables that don't need to live a long time, and thus allocating and freeing them is relatively cheap. Cheap memory = programs go zoom zoom.
With `locals`, nothing gets placed into the short-term memory for the garbage collector, which means we can fit more values inside of there without triggering the "generational check". This is good because that means the garbage collector is doing a lot less useless work (all garbage collection is "useless" - it just frees memory).
Additionally, these values never have to be checked at all by the garbage collector, which frees up even more cycles for your OCaml program to go zoom zoom.
## Locality: Expressiveness
Consider the (simplified) example of some `with_file` function that opens a file, and then executes a function with the file handle. The problem is that we save the file handle to a reference that lives **too long** and thus, is not safe. It will error at runtime, because the file is actually closed when we try to write to it!
```neovim {"update":true,"path":"_/code/1721241757558.ml","timestamp":1725485325831}
<pre>
<span class="Comment"><span class="-spell">(* Opens a file with `name` and executes `f` with the file handle as argument *)</span></span>
<span class="-keyword">let</span> <span class="-variable"><span class="-function">with_file</span></span> <span class="-variable">name</span> <span class="-variable">f</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle</span> <span class="Delimiter">=</span> <span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">open_file</span></span> <span class="-variable">name</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">f</span></span> <span class="-variable">handle</span><span class="Delimiter">;</span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">close</span></span> <span class="-variable">handle</span>
<span class="-keyword">let</span> <span class="-variable">really_bad</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle</span> <span class="Delimiter">=</span> <span class="-variable"><span class="-function">ref</span></span> <span class="Special">None</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">with_file</span></span> <span class="String">"test.txt"</span> <span class="Delimiter">(</span><span class="-keyword">fun</span> <span class="-variable">h</span> <span class="Delimiter">-></span> <span class="-variable">handle</span> <span class="Operator">:=</span> <span class="Special">Some</span> <span class="-variable">h</span><span class="Delimiter">)</span><span class="Delimiter">;</span>
<span class="Comment"><span class="-spell">(* oh no, no we have the handle, but to a closed file! *)</span></span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">write</span></span> <span class="Operator">!</span><span class="-variable">handle</span> <span class="String">"very bad stuff happens now"</span><span class="Delimiter">;</span>
</pre>
```
^1721241757558
Locality provides a way for us to say **in the type system** that a variable is not allowed to escape it's region!
```neovim {"update":true,"path":"_/code/1721242169186.ml","timestamp":1725485325531}
<pre>
<span class="Comment"><span class="-spell">(* Opens a file with `name` and executes `f` with the file handle as argument *)</span></span>
<span class="Comment"><span class="-spell">(* This syntax is maybe not correct, the feature is still getting made by Jane Street *)</span></span>
<span class="-keyword">let</span> <span class="-variable"><span class="-function">with_file</span></span> <span class="-variable">name</span> <span class="Delimiter">(</span><span class="-variable">f</span> <span class="Delimiter">:</span> <span class="-module">File</span><span class="Delimiter">.</span><span class="-type">t</span> <span class="SpecialChar">@ </span><span class="-type">local</span> <span class="Delimiter">-></span> <span class="-type-builtin"><span class="-type">unit</span></span><span class="Delimiter">)</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle</span> <span class="Delimiter">=</span> <span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">open_file</span></span> <span class="-variable">name</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">f</span></span> <span class="-variable">handle</span><span class="Delimiter">;</span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">close</span></span> <span class="-variable">handle</span>
<span class="-keyword">let</span> <span class="-variable">really_bad</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle</span> <span class="Delimiter">=</span> <span class="-variable"><span class="-function">ref</span></span> <span class="Special">None</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">with_file</span></span> <span class="String">"test.txt"</span> <span class="Delimiter">(</span><span class="-keyword">fun</span> <span class="-variable">h</span> <span class="Delimiter">-></span> <span class="-variable">handle</span> <span class="Operator">:=</span> <span class="Special">Some</span> <span class="-variable">h</span><span class="Delimiter">)</span><span class="Delimiter">;</span>
<span class="Comment"><span class="-spell">(* oh no, no we have the handle, but to a closed file! *)</span></span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">write</span></span> <span class="Operator">!</span><span class="-variable">handle</span> <span class="String">"very bad stuff happens now"</span><span class="Delimiter">;</span>
</pre>
```
^1721242169186
```neovim
<pre>
<span class="Comment"><span class="-spell">(* Opens a file with `name` and executes `f` with the file handle as argument *)</span></span>
<span class="-keyword">let</span> <span class="-variable"><span class="-function">with_file</span></span> <span class="-variable">name</span> <span class="Delimiter">(</span><span class="-variable">f</span> <span class="Delimiter">:</span> <span class="-type">local_</span> <span class="-module">File</span><span class="Delimiter">.</span><span class="-type">t</span> <span class="Delimiter">-></span> <span class="-type-builtin"><span class="-type">unit</span></span><span class="Delimiter">)</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle</span> <span class="Delimiter">=</span> <span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">open_file</span></span> <span class="-variable">name</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">f</span></span> <span class="-variable">handle</span><span class="Delimiter">;</span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">close</span></span> <span class="-variable">handle</span>
<span class="-keyword">let</span> <span class="-variable">really_bad</span> <span class="Delimiter">=</span>
<span class="-keyword">let</span> <span class="-variable">handle_reference</span> <span class="Delimiter">=</span> <span class="-variable"><span class="-function">ref</span></span> <span class="Special">None</span> <span class="-keyword">in</span>
<span class="-variable"><span class="-function">with_file</span></span> <span class="String">"test.txt"</span> <span class="Delimiter">(</span><span class="-keyword">fun</span> <span class="-variable">handle</span> <span class="Delimiter">-></span>
<span class="-variable">handle_reference</span> <span class="Operator">:=</span> <span class="Special">Some</span> <span class="-variable"><span class="DiagnosticUnderlineError">handle</span></span><span class="Delimiter">)</span><span class="Delimiter">;</span>
<span class="DiagnosticError"> </span><span class="DiagnosticError">└──── </span><span class="DiagnosticError">This value escapes its region</span>
<span class="Comment"><span class="-spell">(* oh no, no we have the handle, but to a closed file! *)</span></span>
<span class="-module">File</span><span class="Delimiter">.</span><span class="-variable"><span class="-function">write</span></span> <span class="Operator">!</span><span class="-variable">handle_reference</span> <span class="String">"very bad stuff happens now"</span><span class="Delimiter">;</span></pre>
```
## Further Reading:
- [Locality](https://blog.janestreet.com/oxidizing-ocaml-locality/)
- [Ownership](https://blog.janestreet.com/oxidizing-ocaml-ownership/)
- [Parallelism](https://blog.janestreet.com/oxidizing-ocaml-parallelism/)
- https://github.com/janestreet/opam-repository/tree/with-extensions