Parallel
The Parallel module provides synchronous-looking parallel operations that run on separate threads. Unlike async/await patterns, these functions block until completion, making code easier to reason about while still benefiting from parallel execution.
No Colored Functions
Kit avoids the "colored function" problem. Parallel operations look and behave like normal function calls - no async/await, no special syntax. The parallelism is transparent.
Basic Execution
Parallel.run
(fn() -> a) -> Result a String
Runs a function on another thread and blocks until completion.
Returns
Ok result on success, Err message on failure.
result = Parallel.run (fn => expensive-computation 42)
match result
| Ok value -> println "Result: ${value}"
| Err msg -> println "Failed: ${msg}"
Parallel.run-timeout
Int -> (fn() -> a) -> Option (Result a String)
Runs a function with a timeout in milliseconds.
Returns
Some (Ok result) on success, Some (Err msg) on failure,
or None if the timeout expires.
match Parallel.run-timeout 5000 (fn => slow-operation)
| Some (Ok value) -> println "Got: ${value}"
| Some (Err msg) -> println "Failed: ${msg}"
| None -> println "Timed out after 5 seconds"
Parallel Mapping
Parallel.map
List a -> (fn(a) -> b) -> List (Result b String)
Applies a function to each item in parallel.
Returns a list of results in the same order as inputs.
urls = ["https://a.com", "https://b.com", "https://c.com"]
# Fetch all URLs in parallel
results = Parallel.map urls (fn(url) => HTTP.get! url)
# Process results
results |> List.each (fn(r) =>
match r
| Ok body -> println "Got ${String.length body} bytes"
| Err e -> println "Failed: ${e}"
)
Multiple Tasks
Parallel.all
List (fn() -> a) -> List (Result a String)
Runs all functions in parallel and collects all results.
Waits for all functions to complete before returning.
results = Parallel.all [
fn => task1,
fn => task2,
fn => task3
]
println "All tasks completed: ${results}"
Parallel.first
List (fn() -> a) -> Result a String
Runs all functions in parallel and returns the first to complete.
Other tasks continue in the background.
# Return whichever completes first
result = Parallel.first [
fn => fetch-from-primary,
fn => fetch-from-backup
]
Parallel.any
List (fn() -> a) -> Result a String
Runs all functions in parallel and returns the first successful result.
Continues trying until one succeeds or all fail.
# Try multiple sources, return first success
result = Parallel.any [
fn => might-fail-1,
fn => might-fail-2,
fn => should-work
]
match result
| Ok value -> println "Got result: ${value}"
| Err msg -> println "All failed: ${msg}"
Error Types
type ParallelError =
| SpawnError { message: String }
| TimeoutError
| TaskError { message: String }
| InvalidFunction
| ParallelError { message: String }
Complete Example
# Fetch multiple URLs with timeout
fetch-with-timeout = fn(url) =>
Parallel.run-timeout 5000 (fn => HTTP.get url)
# Fetch all URLs in parallel
urls = [
"https://api.example.com/users",
"https://api.example.com/posts",
"https://api.example.com/comments"
]
results = Parallel.map urls fetch-with-timeout
# Process results
results |> List.zip urls |> List.each (fn((url, result)) =>
match result
| Some (Ok response) -> println "${url}: OK"
| Some (Err msg) -> println "${url}: Error - ${msg}"
| None -> println "${url}: Timeout"
)