Runic.Closure (Runic v0.1.0-alpha.7)

Copy Markdown View Source

Serializable closure representation for Runic components.

A Closure combines the source AST, runtime bindings, and compile-time metadata into a single serializable structure. This allows components to be reconstructed from logs using term_to_binary/1 and binary_to_term/1.

Fields

  • :source - The original quoted AST for the closure
  • :bindings - Map of variable names to their captured values
  • :metadata - %Runic.ClosureMetadata{} for environment reconstruction
  • :hash - Content-addressable hash of the closure

Examples

outer_var = 42

closure = Runic.Closure.new(
  quote(do: fn x -> x + outer_var end),
  %{outer_var: 42},
  __ENV__
)

# Closures are serializable
binary = :erlang.term_to_binary(closure)
roundtrip = :erlang.binary_to_term(binary)

# Can be evaluated in a different context
{fun, _} = Runic.Closure.eval(closure)
fun.(10) # => 52

Summary

Functions

Evaluates a closure, returning the result and updated bindings.

Creates a new Closure from source AST, bindings, and caller environment.

Validates that all bindings in a map are serializable.

Validates that a value can be serialized with term_to_binary/1.

Types

t()

@type t() :: %Runic.Closure{
  bindings: map(),
  hash: integer() | nil,
  metadata: Runic.ClosureMetadata.t() | nil,
  source: Macro.t()
}

Functions

eval(closure, opts \\ [])

Evaluates a closure, returning the result and updated bindings.

This reconstructs the evaluation environment from the closure's metadata and evaluates the source AST with the stored bindings.

Options

  • :base_env - Override the base environment for evaluation

new(source, bindings, caller_env_or_metadata)

Creates a new Closure from source AST, bindings, and caller environment.

Validates that all bindings are serializable before creating the closure. Raises ArgumentError if any binding contains non-serializable values.

validate_bindings!(bindings)

Validates that all bindings in a map are serializable.

Raises ArgumentError if any binding is not serializable.

validate_value(value)

Validates that a value can be serialized with term_to_binary/1.

Returns :ok if serializable, {:error, reason} otherwise.

Note: PIDs, references, and ports can technically be serialized but they are not valid across sessions/nodes, so we reject them.