With LUDIC_DEPS=<file> the compiler records every reference the
visibility pass resolves (from module, to module) and every assignment
to another module's global. ludic deps prints the modules,
dependencies, largest cycle, cross writes and globals written from
outside, with --graph, --dot, --writes, --uses MOD, --check FILE and
--baseline FILE. Reseed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A module that says uses must name every package module it reaches; a
package with no module line is named for its directory (ludic_render3d)
for this rule, so a mechanic reaching into the renderer is caught. Only
the engine's runtime needs no naming. 'module x uses' with nothing after
it reaches no other module. A port whose every member has a default
answers with its defaults when unbound, and 'new' of a port says to bind
it. ludic-dev test runs 'ludic test packages'. Reseed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A port is a record of function values a module calls through
(Clock.now()) without naming the module that answers. A port used and
never bound, a bind missing a required member or naming one the port
lacks, and a second bind are refused; the binder must see the port, and
what it binds is checked from its own file. Reseed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A reference from a module that declares uses into a module it does not
name is refused, exported or not, naming the use and the fix. A module
with no uses clause keeps the old rule; a package's module is always
usable; a friend is not held to it; a cycle in the declared graph is
refused; LUDIC_VIS_REPORT=1 lists the violations as uses: lines. Reseed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
property Pool<T> { ... }, function first<T>(xs: []T) -> T, map<T, U> over fn
types; a type writes an instance as Pool<Thing>, nested as deep as needed. The
parser names an instance Pool$Thing and remembers its generic and arguments; the
checker takes the generic declarations out, infers a call's type arguments from
its arguments or its result's declared slot, and makes each instance once as an
ordinary record or function, checked like any other. Errors print Pool<Thing>.
An instance keeps its generic's module and export (L3). ludic-fmt keeps type
arguments together while spacing comparisons and shifts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A barrel's 'module NAME' makes its directory a module; a declaration other modules
use says 'export'. Private use from another module is an error naming the module
and where to mark it; 'friend module' sees everything (a test harness); a file in
no module is public and a package keeps its own module. LUDIC_VIS_REPORT=1 lists
every violation instead of stopping, so a codebase can be given its exports first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>