Skuld.Comp.Env (skuld v0.27.1)

View Source

Environment construction and manipulation.

The Env struct carries scope (handlers, leave-scope, transform-suspend) and effect state. Scope is embedded as a ScopeEnv sub-struct — mutate through Env.* functions rather than reaching into env.scope directly.

Effect State

Effect state lives exclusively in env.state via put_state/3 and get_state/2,3. This map is the only state bucket that survives across fiber suspend/resume cycles — the scheduler threads env.state through all fibers in a pool.

Do not add arbitrary top-level keys to the %Env{} struct itself. Such keys will be lost during fiber execution because the scheduler only preserves scope and state fields. Use put_state/3 for any value that needs to survive across suspensions.

Summary

Types

t()

The environment struct.

Functions

Remove a handler for an effect signature

Get handler for an effect signature (returns nil if missing)

Get handler for an effect signature (raises if missing)

Get the current leave-scope handler (returns identity if nil)

Get the scope sub-struct (for inspection)

Get state for an effect

Get state for an effect, raising if the key is not present (use-after-cleanup guard)

Get the current transform-suspend handler (returns identity if nil)

Get all installed handler signatures

Create a fresh environment with identity leave-scope and transform-suspend

Update state for an effect.

Run the leave-scope chain on a result

Install a handler for an effect signature

Install a new leave-scope handler

Replace the scope sub-struct (for initial construction; prefer with_* functions for mutation)

Install a new transform-suspend handler

Types

t()

@type t() :: %Skuld.Comp.Env{
  scope: Skuld.Comp.ScopeEnv.t(),
  state: %{required(term()) => term()}
}

The environment struct.

Fields

  • scope — scope machinery (evidence, leave_scope, transform_suspend)
  • state — effect state (Writer accumulators, channel state, etc.)

Functions

delete_handler(env, sig)

Remove a handler for an effect signature

get_handler(env, sig)

Get handler for an effect signature (returns nil if missing)

get_handler!(env, sig)

Get handler for an effect signature (raises if missing)

get_leave_scope(env)

@spec get_leave_scope(Skuld.Comp.Types.env()) :: Skuld.Comp.Types.leave_scope()

Get the current leave-scope handler (returns identity if nil)

get_scope(env)

@spec get_scope(t()) :: Skuld.Comp.ScopeEnv.t()

Get the scope sub-struct (for inspection)

get_state(env, key, default \\ nil)

@spec get_state(Skuld.Comp.Types.env(), term(), term()) :: term()

Get state for an effect

get_state!(env, key)

@spec get_state!(Skuld.Comp.Types.env(), term()) :: term()

Get state for an effect, raising if the key is not present (use-after-cleanup guard)

get_transform_suspend(env)

@spec get_transform_suspend(t()) :: Skuld.Comp.Types.transform_suspend()

Get the current transform-suspend handler (returns identity if nil)

handler_sigs(env)

@spec handler_sigs(Skuld.Comp.Types.env()) :: [Skuld.Comp.Types.sig()]

Get all installed handler signatures

new()

@spec new() :: Skuld.Comp.Types.env()

Create a fresh environment with identity leave-scope and transform-suspend

put_state(env, key, value)

@spec put_state(Skuld.Comp.Types.env(), term(), term()) :: Skuld.Comp.Types.env()

Update state for an effect.

Effect state lives in env.state — the only map that survives across fiber suspend/resume cycles. Use module-specific keys (e.g. module attributes or struct-based keys) to avoid collisions between effects.

See the moduledoc for guidance on what belongs in state vs on the Env struct directly.

run_leave_scope(env, result)

Run the leave-scope chain on a result

with_handler(env, sig, handler)

Install a handler for an effect signature

with_leave_scope(env, new_leave_scope)

Install a new leave-scope handler

with_scope(env, scope)

@spec with_scope(t(), Skuld.Comp.ScopeEnv.t()) :: t()

Replace the scope sub-struct (for initial construction; prefer with_* functions for mutation)

with_transform_suspend(env, new_transform_suspend)

@spec with_transform_suspend(t(), Skuld.Comp.Types.transform_suspend()) :: t()

Install a new transform-suspend handler