Logos.Stdlib (Logos v0.2.0)

Copy Markdown

Loads the Layer-2 standard library -- macros and functions written in Logos itself, layered on top of the Elixir-implemented Layer-1 primitives -- into a fresh Logos.Runtime. Source lives as real files under priv/stdlib/ (not embedded Elixir string constants), one per namespace:

  • priv/stdlib/core.logos -> logos.core (the defmacro bootstrap, let/if/when/unless/and/or/defn/defn-/doc/ns)
  • priv/stdlib/seq.logos -> logos.seq (map/filter/reduce/ take/drop/reverse/count/empty?)
  • priv/stdlib/concurrency.logos -> logos.concurrency (receive, atom/deref/swap!/reset!)
  • priv/stdlib/multimethod.logos -> logos.multimethod (defmulti/defmethod)
  • priv/stdlib/set.logos -> logos.set (union/intersection/ difference/subset?/superset?/select/map-invert/ rename-keys)
  • priv/stdlib/walk.logos -> logos.walk (walk/postwalk/ prewalk)
  • priv/stdlib/string.logos -> logos.string (Clojure-idiomatic wrappers over allowlisted String.* Elixir functions -- see that file's own header comment)
  • priv/stdlib/test.logos -> logos.test (deftest/assert/ assert=/assert-throws/run-tests)

logos.map (get/assoc/dissoc) has no .logos file of its own -- it's installed directly by Logos.Primitives.install!/1, since those three need real Elixir map access with no Logos-level way to express it.

Each file is loaded in full (read -> macroexpand -> eval, the same real pipeline any other Logos source goes through -- no shortcut that bypasses it) with the current namespace temporarily switched to its own target namespace, so every def/defmacro in it interns there rather than into logos.core. core.logos loads first: every other namespace below implicitly refers logos.core (the same auto_refer_core? mechanism user and every other namespace get, see Logos.Namespace's moduledoc), so their own source can freely use defn/let/if/etc. unqualified without loading order mattering beyond "core first."

After every file loads, load!/1 refers logos.seq/logos.map/ logos.concurrency/logos.multimethod's public vars into logos.core itself (Namespace.refer!/4). Combined with Logos.Eval.resolve_symbol_location/2's auto-refer-core fallback also checking logos.core's own refers table (not just vars interned directly there), this is what makes e.g. map or get reachable unqualified from user or any other namespace -- exactly the same "usable everywhere with no namespace prefix" property first/let/defn already had when everything lived in one file. logos.set/logos.walk/logos.string/logos.test are deliberately excluded from this refer-into-core step -- each is loaded into every Runtime but only reachable once a caller explicitly (require '[logos.set :refer [:all]])s it (or the logos.test-style equivalent for the other three), matching real Clojure exactly: clojure.set/ clojure.walk/clojure.string/clojure.test are all separate, explicitly-required namespaces there too, never part of clojure.core's own always-available surface -- unlike clojure.core's own multimethod/protocol machinery, which is why logos.multimethod (mirroring that) is auto-referred, alongside logos.seq/logos.map/logos.concurrency.

Summary

Functions

Loads every priv/stdlib/*.logos file into runtime, each into its own namespace, then refers the non-core namespaces into logos.core (see moduledoc). Raises if any form fails to read/expand/eval -- a broken stdlib is a startup-time failure, not a {:error, _} a caller is expected to recover from. Returns runtime for pipelining (Logos.Runtime.new() |> Logos.Stdlib.load!(), exactly what Logos.new_runtime/0 does).

Every file-backed stdlib namespace, in load order (see moduledoc) -- logos.map (primitives-only, no .logos file) is not included. What Logos.StdlibDocs walks to build the generated stdlib reference.

The raw source text for ns's .logos file (one of the namespaces in @files above), embedded at compile time.

Functions

load!(runtime)

@spec load!(Logos.Runtime.t()) :: Logos.Runtime.t()

Loads every priv/stdlib/*.logos file into runtime, each into its own namespace, then refers the non-core namespaces into logos.core (see moduledoc). Raises if any form fails to read/expand/eval -- a broken stdlib is a startup-time failure, not a {:error, _} a caller is expected to recover from. Returns runtime for pipelining (Logos.Runtime.new() |> Logos.Stdlib.load!(), exactly what Logos.new_runtime/0 does).

namespaces()

@spec namespaces() :: [String.t()]

Every file-backed stdlib namespace, in load order (see moduledoc) -- logos.map (primitives-only, no .logos file) is not included. What Logos.StdlibDocs walks to build the generated stdlib reference.

source(ns)

@spec source(String.t()) :: String.t()

The raw source text for ns's .logos file (one of the namespaces in @files above), embedded at compile time.