All pages
Modules and require
Every file is a module with its own scope. require imports named
definitions from a standard module compiled into the binary or from a file
next to yours.
(require "sexpgpu/nn" cross-entropy gpt) ; a standard module
(require "sexpgpu/optim" adamw warmup-stable-decay)
(require "../lib/mine.sx" my-gpt) ; a file, relative to this one
Resolution
| path | resolves to |
|---|---|
sexpgpu/nn, sexpgpu/optim | the standard modules; see nn and optim. Anything else under sexpgpu/ is E-EVAL-033 |
./name.sx, ../dir/name.sx | a file, relative to the directory of the file holding the require, never to a project root or the working directory |
| anything else | E-EVAL-032: a path must start with ./ or ../ |
A file is loaded once per compilation, by canonical path. A cycle is
E-EVAL-030, a missing file E-EVAL-031. Because paths are relative to
the file, every command works from any working directory.
Scope
A file sees three things: the prelude, what it defines, and
the names its requires list. It sees nothing a library required in turn.
- Every top-level definition of a file can be imported; there is no export list. Generated top-level definitions (from a macro) can be imported too.
- A
requirenames at least one definition. Naming something the file does not define isE-EVAL-035, and the fix is the nearest name it does. - A name is bound once per file. Two imports of one name from different
modules, or an import and a local definition, are
E-EVAL-036. - Imported names are not re-exported.
requireruns at module top level, including inside a top-levelprognor a macro expansion. In a local scope it isE-EVAL-034.- Import a name before writing a function or quoted datum that uses its identity; imports do not rewrite symbols already constructed. See macros.
A library macro's expansion keeps the library's symbol identities, so it can call the library's private helpers without the caller importing them. See macros and symbols.
Writing a library
A library is a plain .sx file that your runs require. It can hold
models, schedules and constants shared by several runs, and it can require
sexpgpu/nn for the generic parts:
;;; lib/mine.sx
(require "sexpgpu/nn" rmsnorm linear)
(defvar init-std 0.02)
(defmodel my-gpt (&key vocab layers dim) ...)
A library can also carry diagnostics for its models, off until a run selects them; see writing diagnostics.
A bundle flattens every required file into files/deps/ and rewrites the
paths; see bundle.
Related: the run file, the prelude.