Status
This page says what Sprite is today, in one place. The dated entries of
the file TODO at the root of the repository hold the record behind each
statement; the code wins over both when they disagree.
The front end
Sprite translates Curry to FlatCurry with the Curry front end of PAKCS
3.4.1, the pinned release. The binding optimization of PAKCS is applied
to the FlatCurry file as PAKCS applies it. Sprite’s own port of
icurry 3.1.0 writes the ICurry. The icurry program is an
optional second route that must write the same bytes. PAKCS is also the
oracle of the functional tests. The Curry library is a copy of the
library of that release under curry/lib, with Sprite’s own
Control.SetFunctions. See
Curry to ICurry.
The backend
The C++ backend is the backend (configure --with-default-backend
records the default). It compiles each module to C++ and links it against
the runtime library libcyrt, and its runtime also interprets the
ICurry of a module from a bytecode. A reference implementation of the
same scheduler in Python stays in the tree behind a flag until the removal
gate of issue #82, a month of green nightly runs under the interpreter
modes; the developer notes name the flag, what the
implementation is for, and its limits. curry.save() writes C++
source, and curry.load() reads the shared object of
sprite-make --so; the form of a saved program on the C++ backend is
an open decision of that issue.
The interpreter modes
The flag interpret of the C++ backend selects how a module without a
compiled object runs. tiered, the default, interprets it at once,
compiles it in the background, and swaps its functions to the compiled
code when the object is ready. new interprets it and never compiles
it. all interprets every module. off compiles every module first.
The interpreter takes the same steps as the compiled code and about 1.1 to
1.5 times its time. An installation without a C++ compiler runs every
program interpreted; see Installing and running without a C++ compiler.
The typed boundary
Sprite reads the type scheme of every symbol from the FlatCurry interface
beside its module. curry.expr() types an expression before it
builds it, converts Python values by the expected type, supplies the class
dictionaries, and reports a typing failure at construction with
the error catalogue. A goal without a type signature keeps
its class constraints, and curry.eval(), the REPL, sprite-exec
-g and curry.save default them with the table of the PAKCS REPL
(Defaulting of class constraints). A text goal may end in where x free, and
its values carry the bindings. Open from the plan of epic #48: the
schemes as metadata of the generated modules instead of the interface
reads, the specialization of a saturated method call, and a random
harness over the engine.
The performance record
The committed records are under tests/data/curry/benchmarks/results,
one JSON Lines file per suite and run. The record of the C++ backend
after Phase 2 of the performance program is the label
phase2-2026-10-04, in the files phase2-2026-10-04-throughput.jsonl
and phase2-2026-10-04-memory.jsonl: the nightly set of ten programs,
three repetitions. The baseline before the program is the label
baseline-2026-10-03 (four suites, Sprite and PAKCS).
Performance tabulates the records and names the harness commands.
Two measured facts. In the memory record of that label Tak1 peaks at
68 MB with the collector and 1009 MB without it. The rotation check of
the scheduler costs 3 to 5 instructions per completed step over the build
before the ticker (the TODO entry on K1 and K2).
Known limits
Arithmetic on a free variable of a built-in type suspends the evaluation;
==on such a variable in a required position binds it through the binding optimization, and=:=always does (issue #37).There is no debugger for a non-deterministic computation. The aids are
sprite-exec --stats, the counters ofmake COUNTERS=1, the generated code of a function (curry.inspect.getimpl), and the reference implementation of the developer notes.A name produced by a functional pattern stays narrowed, and every later comparison of it resolves the narrowing again; read such a result through a set function (issue #86; the note in Pattern Matching).
The mixed mode of tiered execution has gaps. A module whose tables changed shape after its shim was made stays interpreted, with the modules that import it, and one warning says so. A swapped module keeps its registry entry for the life of the process, so a later load of the same name from another directory is refused, before the object is opened.
curry.load()of the object of a module whose background compile runs waits for the compile; the object of a module that stays interpreted is refused, and a new process loads it. An edited source is not read again in one process: the import says so, and the swap refuses an object compiled from the edited file. A program shorter than its compile ends interpreted with no object written.showof aFloatfollows PAKCS.
What is experimental
The Memory Pool System collector (
make GC=mps), behind a gate; the default collector is the mark-and-sweep collector of the block heap.The write counters of the collector (
make GC_WRITE_COUNTERS=1) and the scheduler counters (make COUNTERS=1): instrumentation for the measurements of the generational design and of the parallel-evaluation gate, off in the default build.The conda recipe under
conda/: a scaffold, not published.The ICurry cache (
SPRITE_CACHE_FILE): off by default outside the test drivers;configure --cacheturns it on (see Development Variables).
Where the plan lives
The tracker is the issue list of the repository on GitHub. The milestone is number 1, “Sprite resuscitated”; its page lists the open items. The epics are these issues:
#6, measurement infrastructure.
#11, CI and test-suite speed.
#14, interactive latency.
#19, throughput of the C++ runtime.
#24, memory management.
#28, parallel evaluation, behind a gate.
#30, the future of the reference implementation (its retirement is #82).
#40, developer velocity.
#48, the typed boundary between Python and Curry.
#67, Phase 3: optimizer passes, native workers, ticker rotation, pointer tagging.
#87, an array IR example and the bulk boundary.