Logos. Namespace
(Logos v0.2.0)
Copy Markdown
Functions operating against a Logos.Runtime's ETS table -- there is no
free-floating %Logos.Namespace{} struct someone could get out of sync
with the registry; every operation here reads/writes runtime's table
directly. See Logos.Runtime's moduledoc for the exact row shapes.
A namespace row is %{meta:, aliases:, refers:, auto_refer_core?:, var_names:}:
aliases--%{alias_name => target_ns_name}, populated byalias!/4(theLogos.Var-analogue of:require ... :as).refers--%{name => {target_ns_name, target_name}}, populated byrefer!/4(:refer/use).var_names-- theMapSetof names interned directly in this namespace (viaintern!/5), kept forrefer!/4's "every public var this namespace defines" enumeration and for qualified-symbol existence checks.auto_refer_core?-- every namespace exceptlogos.coreitself implicitly seeslogos.core's public vars, so the standard library (interned intologos.coreby both the Layer-1 primitives andpriv/stdlib/*.logos's Layer-2 macros/functions) is visible everywhere without an explicitrequire. Implemented as a resolution-time fallback (Logos.Eval.resolve_symbol_location/2checkslogos.coredirectly when this flag is set and nothing else matched) rather than as a literal one-time copy intorefers: a snapshot-copy taken atensure!/2time would go stale the momentlogos.coregains a new var afterward (exactly what happens during bootstrap:userisensure!'d before thepriv/stdlib/*.logosfiles finish loadingif/let/etc. intologos.core). Resolving dynamically instead meansuser(and every other namespace) always sees the current contents oflogos.core, which is both simpler to get right during bootstrap and arguably closer to what "implicit refer" should mean.
Summary
Functions
Registers alias_name -> target_ns_name in ns_name's alias table.
Every namespace name currently registered in runtime.
Replaces ns_name/var_name's metadata with fun.(old_meta).
Whether ns_name implicitly refers logos.core (true for every namespace except logos.core itself).
Creates namespace name if it doesn't already exist. Idempotent. logos.core itself never auto-refers itself.
Whether namespace name exists in runtime.
Looks up name in ns_name's explicit refers table only (not the implicit logos.core fallback -- see Logos.Eval.resolve_symbol_location/2 for the full chain).
The raw %{value:, meta:} row for ns_name/var_name, or :error if no such Var.
The current value of ns_name/var_name, or :error if no such Var.
Whether ns_name interns a var literally named var_name (not via refer).
Interns (creates or overwrites) var_name in ns_name with value, merging meta into the Var's metadata. Creates ns_name first if absent.
Whether ns_name/var_name is public, i.e. its metadata's :private key is not truthy. A nonexistent Var is not public.
Pulls public vars from from_ns into ns_name's refers table
(:only/:exclude supported; :rename is not implemented). Private
vars (:private truthy in metadata, checked via public?/3) are never
referred, regardless of :only/:exclude -- require/use only ever
refer public vars.
Resolves alias_or_ns against ns_name's aliases, falling back to treating it as a literal namespace name if no alias matches. Used when resolving a qualified symbol like ns/name.
The (meta, aliases, refers, var_names, auto_refer_core?) row for name, or :error if it doesn't exist.
Mutates ns_name/var_name's value in place (the Logos.Var "mutable box" -- see that module).
Types
Functions
@spec alias!(Logos.Runtime.t(), String.t(), String.t(), String.t()) :: :ok
Registers alias_name -> target_ns_name in ns_name's alias table.
@spec all(Logos.Runtime.t()) :: [String.t()]
Every namespace name currently registered in runtime.
@spec alter_meta!(Logos.Runtime.t(), String.t(), String.t(), (map() -> map())) :: :ok | {:error, {:no_such_var, String.t(), String.t()}}
Replaces ns_name/var_name's metadata with fun.(old_meta).
@spec auto_refer_core?(Logos.Runtime.t(), String.t()) :: boolean()
Whether ns_name implicitly refers logos.core (true for every namespace except logos.core itself).
@spec ensure!(Logos.Runtime.t(), String.t()) :: :ok
Creates namespace name if it doesn't already exist. Idempotent. logos.core itself never auto-refers itself.
@spec exists?(Logos.Runtime.t(), String.t()) :: boolean()
Whether namespace name exists in runtime.
@spec get_refer(Logos.Runtime.t(), String.t(), String.t()) :: {:ok, {String.t(), String.t()}} | :error
Looks up name in ns_name's explicit refers table only (not the implicit logos.core fallback -- see Logos.Eval.resolve_symbol_location/2 for the full chain).
@spec get_var_row(Logos.Runtime.t(), String.t(), String.t()) :: {:ok, %{value: term(), meta: map()}} | :error
The raw %{value:, meta:} row for ns_name/var_name, or :error if no such Var.
@spec get_var_value(Logos.Runtime.t(), String.t(), String.t()) :: {:ok, term()} | :error
The current value of ns_name/var_name, or :error if no such Var.
@spec has_var?(Logos.Runtime.t(), String.t(), String.t()) :: boolean()
Whether ns_name interns a var literally named var_name (not via refer).
@spec intern!(Logos.Runtime.t(), String.t(), String.t(), term(), map()) :: :ok
Interns (creates or overwrites) var_name in ns_name with value, merging meta into the Var's metadata. Creates ns_name first if absent.
@spec public?(Logos.Runtime.t(), String.t(), String.t()) :: boolean()
Whether ns_name/var_name is public, i.e. its metadata's :private key is not truthy. A nonexistent Var is not public.
@spec refer!(Logos.Runtime.t(), String.t(), String.t(), keyword()) :: :ok | {:error, {:no_such_namespace, String.t()}}
Pulls public vars from from_ns into ns_name's refers table
(:only/:exclude supported; :rename is not implemented). Private
vars (:private truthy in metadata, checked via public?/3) are never
referred, regardless of :only/:exclude -- require/use only ever
refer public vars.
opts:
:only-- a list ofString.t()names; when given, only those names (still filtered throughpublic?/3) are referred.:exclude-- a list ofString.t()names to skip.
@spec resolve_alias(Logos.Runtime.t(), String.t(), String.t()) :: String.t()
Resolves alias_or_ns against ns_name's aliases, falling back to treating it as a literal namespace name if no alias matches. Used when resolving a qualified symbol like ns/name.
@spec row(Logos.Runtime.t(), String.t()) :: {:ok, row()} | :error
The (meta, aliases, refers, var_names, auto_refer_core?) row for name, or :error if it doesn't exist.
@spec set_var_value!(Logos.Runtime.t(), String.t(), String.t(), term()) :: :ok | {:error, {:no_such_var, String.t(), String.t()}}
Mutates ns_name/var_name's value in place (the Logos.Var "mutable box" -- see that module).