Expand description
What a new process runs: a function value turned back into code.
spawn(f, args) hands the new process the code of f and copies of the
values it reaches, never a reference into the spawner’s environment. That
is Erlang’s rule for a fun sent to spawn, and it is the only reading of
“processes share nothing” that survives a function value: a closure carries
its defining environment, and sharing that environment is the coupling
process isolation exists to remove (mailbox::deep_copy refuses closures
for the same reason).
So the spawner’s function is walked, not shared:
- every free name it reaches that is bound to a function becomes a definition in the child, recursively, so helpers come along;
- every free name bound to data becomes a binding in the child, a deep copy taken now (a local the closure captured, a top-level constant);
- a name bound to a builtin is left alone: the child has its own runtime;
- a name bound to anything else (a host handle, a promise) is refused by name, because a process must open its own resources.
The result is compiled for the bytecode VM, because the VM is the executor that can preempt and park; a function the tree-walker defined is recompiled, not called across.
Structs§
- Code
- A process’s program: definitions, data bindings, and the form it starts at.
Enums§
- Entry
- How the code reached its entry function.
Functions§
- call
(f a1 a2 …)where each argument is a global holding a copied value.- define_
value (define name value-form).- function_
code - The definitions and bindings
freaches, withfitself defined underas_name. What a migration installs and a server’s handler starts from. - is_
function - Is this value something
spawncan run? - name_of
- The name a function value was defined under, if it has one. What
defmigratematches running processes by. - spawn_
code - The code that runs
f(args…)in a new process. - symbol
- A symbol form.