# 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.

```lisp
(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](https://sexpgpu.041.io/docs/nn.md) and [optim](https://sexpgpu.041.io/docs/optim.md). 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](https://sexpgpu.041.io/docs/prelude.md), what it defines, and
the names its `require`s 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 `require` names at least one definition. Naming something the file does
  not define is `E-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.
- `require` runs at module top level, including inside a top-level `progn`
  or a macro expansion. In a local scope it is `E-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](https://sexpgpu.041.io/docs/macros.md#generated-declarations).

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](https://sexpgpu.041.io/docs/macros.md#symbols-and-capture).

## 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:

```lisp
;;; 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](https://sexpgpu.041.io/docs/writing-diagnostics.md).

A `bundle` flattens every required file into `files/deps/` and rewrites the
paths; see [bundle](https://sexpgpu.041.io/docs/bundle.md#layout).

Related: [the run file](https://sexpgpu.041.io/docs/run-file.md), [the prelude](https://sexpgpu.041.io/docs/prelude.md).

---

SexpGPU documentation. Every page: https://sexpgpu.041.io/llms.txt
