This is a very imprecise, possibly broken, probably outdated roadmap for SPy.
The reason it exists is to give a very rough idea of the past and future trajectory of the project at the time of writing, but it can change at any time depending on the findings and the needs.
Last updated on 2026-04-17.
The roadmap is divided into multiple pillars. Each pillar can be pursued more or less independently of the others, although they are often interconnected. We intentionally don't put an expected completion date.
The pillars are:
-
core language: features to make the SPy language more generally useful. A lot of the innovative stuff like redshifting and compile-time metaprogramming go here.
-
stdlib: libraries written in SPy itself; lives in
stdlib/*.spy. Often these tasks depends on one or more "core language" features. -
Memory managment: integration with refcounting and/or other GCs.
-
SPy/C integration: make it possible to seamlessly use C libraries from SPy programs.
-
SPy/Python integration: make it possible to seamlessly
importpython libraries in SPy, and SPy libraries in python.
Northern star: have enough features to be able to write the SPy interpreter in SPy itself.
Smaller goals: have enough features to:
-
implement advent of code problems;
-
write simple CLI tools;
-
write an efficient interpreter for a toy language.
-
implement a
print()with variable number of arguments (requires some kind of macro-like functionality) -
blue-time support for
*argsand**kwargs -
implement f-strings
✅ dict literals: spylang#342
✅ support for CLI arguments: spylang#353
✅ support for preliminary file I/O: spylang#447
✅ compile-time friendly tuple: spylang#402
✅ implement is and is not: spylang#428
✅ PEP 695 syntax sugar for @blue.generic functions: spylang#437
✅ add support for default arguments: spylang#442
✅ f32 and complex types: spylang#347 spylang#398
✅ better debugging
-
✅ SPy-level tracebacks
-
✅
breakpoint
✅ list literals
✅ better error messages (e.g. turn AssertionErrror into proper messages)
✅ better blue/red checks (e.g. raise an error if we call a blue function with red arguments)
✅ refactor __dunder__ methods and introduce metafunctions
✅ blue-time descriptor protocol
✅ for loops, range, iterator protocol
-
enough metaprogramming capabilities to implement e.g.
dataclasses -
serialization of the "live image" after redshifting
-
support for heap-allocated
classes -
support for
withand context managers -
support for
try/catch(currently allraiseare turned into panics)
- write
strandbytesin pure SPy
✅ preliminary file object: spylang#447
✅ improve standard builtin types:
- add support for slices: spylang#345
- add
str.replace: spylang#394 - spylang#460
✅ introduce the stdlib directory and add support for importing from there
✅ stdlib/_list.spy
✅ stdlib/_dict.spy
✅ stdlib/array.spy
-
preliminary
socketsupport -
continue improving
list,dictand other builtin types with the missing functionalities -
improve
array, which is very limited and just a PoC by now -
more stdlib modules; the following is a non-exahustive list but gives an idea of what might be needed:
-
datetime -
argparse -
json
-
-
full support for I/O, removing ad-hoc builtins and using a more general mechanism to call C libraries provided by SPy/C
✅ distinguish between gc_alloc and `raw_malloc: spylang#371 spylang#383
✅ introduce gc_ref and raw_ref
✅ Add support for Boehm GC spylang#383
-
distinguish between pointer-to-object, pointer-to-unbounded-array and pointer-to-bounded-array (similar to e.g. rust slices);
-
add basic refcounting support. In pure-SPy configuration it will be basic refcounting without any cycle detection; when SPy/Python integration is enabled, it will map to
Py_IncRef/Py_DecRefand rely on CPython's GC for cycle detection; -
experiment with Whippet
Northern stars: be able to implement posix, socket, and sqlite by wrapping C libraries
Requirements/misc notes:
-
"CFFI for SPy" (which is VERY different than "use CFFI to create CPython bindings")
-
generic way to interface with external C libraries
-
need to work both in the interpreter and in the compiler
-
unclear how it works with WASM-centric interpreter
-
related work: Zig's
@cImport
- start to experiment with it
This is easy but limited: SPy code is translated to C, wrapped by cffi and then
imported into CPython. It works only one way and with very limited types (scalars and
arrays). It's good enough to pass e.g. numpy arrays and doing unumerical computations
in SPy, though.
DONE in Q2/2025:
- ✅ introduce the
py-cffioutput kind
TODO:
- automatic conversion of
array.spytypes to and from CPython'smemoryview/np.array
This is the ultimate goal for SPy/Python integration, allowing seamless interop between the two.
The plan is the following:
-
SPy programs can be compiled to standalone executable or CPython extension modules
-
when targeting CPython modules, SPy essentially becomes a "better Cython"
-
when targeting a standalone executable, SPy programs can opt-in for CPython compatibility
When CPython compatibility is disabled:
-
executables are self-contained
-
they can be statically linked
-
they don't require
libpython.so -
they can choose multiple memory management strategies (refcounting or other GCs)
When CPython compatibility is enabled:
-
the SPy program essentially becomes a CPython module
-
SPy can
importarbitrary Python modules -
the executable links to
libpython.soand calls themainfunction in the SPy module -
refconting is mandatory
The actual interop between SPy and Python will be implemented in pure SPy, by calling
the corresponding Py* functions exposed by Python.h.
This task requires:
-
SPy/Cintegration (to be able wrap and callPython.hfrom SPy) -
refcounting memory model
✅ rework CLI using subcommands instead of flags: spylang#332
✅ docs skeleton and automation: spylang#349
✅ switch documentation to mkdocs-material: spylang#372
✅ HTML backend for AST visualization: spylang#413 spylang#414 spylang#424
✅ playground: share button and snippet links: spylang#427