spawn
result = spawn("fnName", arg1, arg2, ...)
Input: "fnName", arg1, arg2, ... · Output: result
What it is
Runs an already-defined user function on rayon's global thread pool (the Worker abstraction). "fnName" (string) names a function already defined in this script; arg1, arg2, ... (any number of values of any type, zero or more) are forwarded to it positionally, exactly as if calling it directly. The worker gets an ISOLATED snapshot of the current globals and function table plus a freshly-drawn RNG seed — never the live shared environment — so nothing a worker does can race with the caller or another worker. Only a user-defined function can be spawned, never a builtin (builtins like plot/savefig mutate state with no meaning off the main thread).
Overloads
One call shape — this function is not overloaded.
| Code | Input | Output | Description |
result = spawn("fnName", arg1, arg2, ...) | "fnName" string"fnName" (string) names a function already defined in this script.arg1 numberarg1, arg2, ... (any number of values of any type, zero or more) are forwarded to it positionally, exactly as if calling it directly.arg2 numberarg1, arg2, ... (any number of values of any type, zero or more) are forwarded to it positionally, exactly as if calling it directly.... number, repeatablearg1, arg2, ... (any number of values of any type, zero or more) are forwarded to it positionally, exactly as if calling it directly. | result Worker or Mutex | Returns a Worker handle (a lightweight opaque token, type(w) == "worker") immediately, before the function has necessarily finished; join/worker_done observe completion via a Mutex+Condvar under the hood, since the pool's own dispatch is fire-and-forget. |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
heavy(n) := n * n
w = spawn("heavy", 6)
print(join(w)) # 36
36
from concurrency
heavy(n) := n * n
w = spawn("heavy", 7)
result = join(w)
print("result = {result}")
result = 49
from quickstart
heavy(n) := n * n
w = spawn("heavy", 7) # runs on its own OS thread
while not worker_done(w) # non-blocking poll; handle stays valid
end while
result = join(w) # blocks for the result (49)
print(result) # 49
49
from concurrency
heavy(n) := n * n
w = spawn("heavy", 7)
print("spawned result {join(w)}")
results = zeros(10)
parallel for i in 0 to 9
results[i] = heavy(i)
end parallel
print("parallel results {results}")
spawned result 49 parallel results [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
from specialized
How it works
spawn("fnName", arg1, arg2, ...) runs an already-defined user function (one-line := or block function ... end) on its own OS thread, the Worker abstraction (§47/§54): an ISOLATED environment (a full snapshot of the current globals and function table, plus a freshly-drawn RNG seed), never the live shared env — so nothing a worker does can race with the calling script or with another worker. Only a user function can be spawned (not a builtin): builtins like plot/savefig mutate figure/output state that has no meaning off the main thread. Returns a Value::Worker handle; get the result (blocking) with join(w).
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.