Schooner.Environment (schooner v1.0.0)

Copy Markdown View Source

Opaque embedding-friendly environment that bundles a runtime Schooner.Env, an expander SyntaxEnv, and a library registry.

An %Environment{} is the recommended argument to Schooner.eval/2,3 and Schooner.eval!/2,3 for embedders. It carries everything needed to evaluate a script in a controlled surface — which standard libraries are reachable via (import ...), which host libraries are pre-applied, which named host libraries are available for the script to import. The struct is opaque: embedders must not pattern-match on its internals; the public surface is new/1.

Library composition

  • Standard libraries populate the registry from Schooner.Library.standard/0. The :standard_libraries option controls which ones are available. Default :default registers everything Schooner ships with; :none ships none; a list of canonical names like [["scheme", "base"], ["scheme", "char"]] ships exactly those.

  • Named host libraries (built with Schooner.Host.library/1 and a non-empty :name) join the registry alongside the standard libraries. The script must (import ...) them to bring their bindings into scope. Sandbox-safe — the embedder controls the menu, the script controls which dishes it orders.

  • Anonymous host libraries (name: []) bypass the registry entirely. Their bindings are applied directly to the runtime env at construction time, so they are in scope from the script's first form without any (import ...). This is sandbox-loosening — list anonymous libraries deliberately.

  • :pre_imports auto-apply specific named libraries to the runtime env, equivalent to the script having (import (foo bar)) at the top. Useful when the embedder always wants a specific surface available without making the script repeat the import. Only canonical names are accepted at this level (no modifiers); use anonymous libraries or script-side (import (only ...)) for finer control.

Re-use across evaluations

An %Environment{} can be passed to many Schooner.eval/2,3 calls. The runtime env's globals slot persists across evaluations, so a script's top-level defines remain visible to later scripts evaluated against the same environment. This is the embedding-friendly model for things like rule-loading: load rule definitions once, evaluate many trigger scripts that call them.

Each call to eval snapshots and restores the per-process exception / continuation / parameter state, so leftover state from a script that escaped via raise does not bleed into the next call.

Summary

Functions

Build a new %Environment{}.

Types

t()

@opaque t()

Functions

new(opts \\ [])

@spec new(keyword()) :: t()

Build a new %Environment{}.

Options

  • :standard_libraries — controls which shipped libraries enter the registry. One of:

    • :default (default) — every shipped library.
    • :none — empty registry.
    • a list of canonical names (e.g. [["scheme", "base"], ["scheme", "char"]]) or atom shortcuts (:base, :char, :inexact, :complex, :cxr, :write, :read, :lazy, :case_lambda / :"case-lambda").
  • :libraries — list of Schooner.Library.t/0 (typically built via Schooner.Host.library/1). Named libraries join the registry; anonymous libraries (name: []) have their bindings applied directly to the runtime env.

  • :pre_imports — list of canonical library names to auto-import at construction time. Each name must resolve against the assembled registry (standard + named host libraries) — a missing name raises Schooner.Library.NotFoundError.

Returns the constructed %Environment{}. Raises ArgumentError for malformed option values.