En 30 secondes
In the second OCaml Unboxed lesson on experimental locals, the speaker extends local annotations from parameters to variables and return values. Compiler examples show escape errors, special treatment of tail positions, and how `exclave_` and a local return annotation allow a greeting list to be allocated in the caller's region.
- 1Local variables cannot escapeAssigning local `x` into a longer-lived string reference produces an escape error.
- 2A local tuple can contain localsThe compiler infers that a tuple containing local values is local when the tuple itself does not escape.
- 3Tail positions are specialThe same `ignore` call can fail in return position; the speaker defers the detailed rules.
- 4A helper needs locality in its typeAn ordinary `string -> string list` signature does not promise that its argument stays local.
- 5End the region early`exclave_` makes the greeting list part of the outer region, while `local_` on the return communicates the calling convention and result locality.
- 6Parameters and local aliases differThe example compiler permits the parameter in the exclave but rejects a local alias defined inside the function.
À retenir
- A local variable cannot escape its region, including through a longer-lived reference.
- A structure containing local values can itself be local if it does not escape.
- Return or tail positions have special locality rules that the speaker leaves for a later lesson.
- `exclave_` ends a function's region early so the following expression can allocate in the outer region.
- A local return annotation signals possible allocation in the caller's region and a result that must not escape it.
- In the example, a local parameter can be used inside an exclave, while a locally bound alias cannot.
Lire le texte remanié, chapitre par chapitre
Local variables and escape
The speaker reviews local parameters and adds a local variable to an imperative function. Storing it in a reference produces an escape error.
Last time we saw a local parameter: the value received as an argument does not escape its region, so the function does not store it or put it in a structure that will be stored elsewhere. Today I want to generalize that to local variables and explain why we might need a local return value.
I'll start with a small imperative function of type `unit -> unit` and bind `x` using `let local_ x = "you"`. The annotation tells me that even if the function contains complicated imperative code, it cannot store this local value somewhere that lets it escape.
For example, I create a string reference outside the function and try to assign `x` to it. The compiler reports that the value escapes its region, exactly as the local annotation should prevent. Removing the assignment restores the working program.

Ignoring locals and tail positions
The experimental compiler needs a locally typed `ignore` in this example, and it can infer a local tuple. Return positions follow special rules that will be explained later.
Even using the built-in `ignore x` gives an escape error in the experimental compiler shown here: the built-in function does not yet know about locals. I define another `ignore` with type `local_ 'a -> unit`, and the program works. This feature is under development, so there are still rough edges.
I add another local variable `y` and pass `(x, y)` to the local-aware `ignore`. Neither value escapes merely because it is placed in a tuple: the tuple itself does not escape. The compiler infers that the structure containing the locals must itself be local.


There is a complication if I put `ignore (x, y)` directly in the function's return position: the compiler reports an escape. Return positions, also called tail positions, have special locality rules. I will explain those rules in a future video; for now I move the call out of return position and return `()` afterward.
Refactoring a greeting function
A helper that builds a list reveals why parameter and return locality matter. The initial signatures allow or cause escapes.
Next I build local greeting lists for `x` and `y`, each containing `"Hello,"` and the corresponding value. The code works, but it repeats the same operation. To avoid duplication I extract a helper `greet` taking a string and returning a string list.
Calling the helper with local `x` fails. Its ordinary type, `string -> string list`, says nothing that promises the argument will not be stored somewhere or otherwise escape. Marking the parameter `local_` makes that promise, but then the compiler reports another error: the implementation puts the local parameter into a list that it returns.


What I want is for the list to belong to the surrounding region rather than the helper's own region. The general rule is that a local value must not escape its region. Every function defines a region, and without a change, putting the local parameter into the returned list looks like an escape.
Exclaves and local returns
The speaker uses `exclave_` to end the helper's region before allocating the list in its caller's region. A local return annotation signals that allocation and prevents the result from escaping.
The keyword `exclave_` ends `greet`'s region early, before the list is constructed. The parameter `z` came from an outer region, so using it after the inner region ends does not make it escape that region. The newly constructed list is also allocated outside `greet`'s region, in the caller's region.
There is still an error until I mark the return as local. The compiler reports that a value escapes its region; I think that message is misleading in this case, although there is a good reason for the type error. The function must signal that it may allocate in its caller's region so the calling convention works.

A `local_` return annotation communicates two things: the function may allocate in its caller's region, and the returned value is local and cannot escape that region. With both the annotation and `exclave_`, the example compiles. I can use `greet` for both local variables.
To recap, the local parameter permits `greet` to receive `x`; `exclave_` ends the helper's region before the list is built; and the local return annotation says the result is allocated locally in the parent and cannot escape further. The compiler knows that a parameter came from an outer region.
A local alias inside an exclave
A local alias of the parameter cannot be used inside the exclave in the example. The speaker notes that local parameters and local variables differ.
There is a subtle difference between a local parameter and a local variable. If I bind `let local_ a = z` inside `greet` and use `a` in the exclave, the compiler rejects it: the local variable cannot be used there. We have lost the fact that this binding came from the outer region. I'll explore the distinction further in a future video.

Sur la même chaîne
1:48:29EN
1:36:37EN
1:05:45EN
1:25:00EN
1:16:29EN
27:39EN