Qu

spawn

Builtin index · Concurrency

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.

CodeInputOutputDescription
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

output
36

from concurrency

heavy(n) := n * n

w = spawn("heavy", 7)
result = join(w)
print("result = {result}")
output
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

output
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}")
output
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.