Sun Language Roadmap
Features Sun still needs, ordered by priority — highest first. Completed features are removed from this list rather than ticked off.
The guiding principle: prioritise the work that turns "wait for the compiler team" into "a user can do it themselves". Table stakes before novelty.
Optionals — Remaining Work
Option<T> ships in the stdlib (stdlib/option.sun); _Result<T, E> is builtin
and usable without the standard library. Both use generic payload enums with owning
payloads and drop glue. The absence APIs
(Map.find, String.find_char/rfind_char, Vec.first/last/pop,
LinkedList.first/last) return Option<T>, and the iteration protocol
(stdlib/iterator.sun) is next(ref Container) Option<T>. What remains:
- Niche-optimised representation where possible (e.g.
Option<raw_ptr<T>>as a nullable pointer) - Bare
Some/Noneprelude names (today it isOption.Some(x)/Option.None) - Explicit
Option<i32>.Some(...)in expression position - Nested-generic payload unification
- Arrays and globals of payload enums
- C-ABI classification of payload enums
- Nested patterns in
match -
DW_TAG_variant_partdebug info for payload enums
Constants and Compile-Time Evaluation
Routine requirements in embedded and safety-critical work, not niceties.
Fixed-size array types (array<i32, 4>, array<f64, 2, 3>) exist, own their
elements inline, and their dimensions are part of the type. Constant
expressions, including calls to pure functions, are evaluated at compile time,
and an array size can be the name of a constant: array<T, N>.
- Generic value parameters:
array<T, const N> - An array size computed by a function call, when the size is used by a class field or a function signature, or the function is declared below the use
- Place compile-time
constglobals in read-only memory
Iteration Ergonomics
for (var x: Type in iterable) works but requires an explicit type annotation and
there are no adapters. Verbose iteration is the first thing people mention when
they bounce off a language.
- Infer the element type in
for ... in - Iterator adapters (
map,filter,take,zip,enumerate) - Ranges as iterables
- Iteration over a constant container:
next(ref Container)takes a mutable borrow, sofor … inneeds avariterable
Language Server Navigation
The LSP serves diagnostics, formatting, semantic tokens, hover type
information, go-to-definition, find references and rename symbol today, plus
a VS Code extension in extensions/vscode-sun. Autocomplete is the gap.
- Autocomplete (must hide items that are not accessible from the cursor's
module — use
sun::access::isAccessible)
Testing
-
sun testrunner (also emitted as a second<output>_testbinary by-c; tests run in parallel by default,--test-sequentialopts out) - Test declarations in
.sunsource (test_function, manifesttest_files:) - Assertion builtins with useful failure output (
std.test) - Test filtering (
--test-filter geometry.*, repeatable, exact / module prefix / trailing-star patterns; a runtime argument like--test-sequential) - A thread pool for very large suites (today: one thread per test)
Error Handling Improvements
- Stack traces on errors
-
panic/assertbuiltins - Error context and chaining
Library Expansion
Roughly 5,000 lines of stdlib today. Files and directories (std.io),
environment (std.env), processes (std.process) and clocks (std.time) all
exist. Every item below is something a first-day user hits. Most are
community-supplyable now that FFI has landed.
- Regex (expose the existing parser)
-
externdeclarations for C globals and iterablestd.env.Env - File metadata beyond exists/size, via
statx(the one stat-family call whose struct has the same layout on every architecture) - Buffered stdin;
std.io.read_linereads a byte at a time so it cannot swallow input a child process is about to read -
String.c_str()as aconst method: it writes the terminating NUL on demand, so every path-taking function (std.io,std.env,std.process) still takesref String. Keeping the NUL as an invariant of the buffer would let them takeconst ref String. TLS is in the same position:TlsStream.connectandHttpsClient.gettake the host asref Stringfor exactly this reason
Networking and TLS
TLS client and server transports, hostname resolution and an HTTPS client have landed:
tls.moon wraps OpenSSL and carries a static copy of it, so TLS programs
need no linker flags and no OpenSSL on the target. Remaining work:
- Integrate
TlsServerContextwithHttpServerso it can serve HTTPS - IPv6, and connect/read timeouts on both
TcpStreamandTlsStream - Redirect following and connection reuse in
HttpsClient - Fetch remote
.moonbundles with the native client instead of shelling out tocurl, dropping the package'scurldependency - Cross-target archives:
tls.moonis built natively per platform — x86-64 musl archives on Linux (scripts/fetch-openssl.sh), arm64 Darwin archives on macOS (scripts/build-openssl-macos.sh), each selected by the manifest'starget:block. What's missing is archives for cross builds (an aarch64 Linux target, or a Darwintls.moonbuilt from a Linux host) — thetarget:block also selects per OS only, not per architecture - Revisit the backend behind the same Sun API — a smaller vendored TLS library, or a pure-Sun implementation, without changing user code
Data Structures
Vec<T>, Map<K, V>, LinkedList<T>, Queue<T>, ContiguousBuffer<T>,
String, Matrix<T>, BigUint, Unique<T> and Shared<T> exist today.
-
Set<T> -
Stack<T> -
OrderedMap<K, V>
Language Odds and Ends
- Generic overloads that differ only in their constraint (one name, same
parameter shape,
<F: _Lambda>vs<F: _Function>) — duplicate generic declarations are rejected until overload resolution supports constraints (#194);spawnuses the union trait_Callableinstead - Interface inheritance (
src/semantic_analysis/scope_variables.cpp:876) - More sophisticated borrow tracking for ref params
(
src/borrow_checker/borrow_checker.cpp:385) - Proper float printing;
print_f64truncates to an integer (src/codegen/intrinsics/print.cpp:344)
Other Tooling
- Linter (
sunlint) - Source maps for error traces
- Re-enable the
DISABLED_tests intests/tooling/frontend/test_lexer.cpp
Native Protobuf Import — Deferred Items
protos: manifest imports synthesize Sun source per message (encode/decode,
_delimited framing, Option<T> for proto3 optional, payload enums for
oneof, unknown-field preservation, .moon export), byte-identical to
libprotobuf. Docs: docs/pages/protobuf.mdx. Deferred:
- proto2 syntax
-
group - Extensions
- Recursive messages by value (need indirection)
-
--dump-proto-sunin the LSP
MacOS Target
Cross-compiling from Linux works and is covered by tests: --target arm64-apple-darwin produces Mach-O objects and a Darwin stdlib.moon
(Apple AAPCS64 rules, per-OS stdlib sources via the manifest's target:
block, __ulock in place of futex). The native-host support — Homebrew
build, JITLink object layer, macOS search paths and a macos-latest CI job
— is implemented but has not yet run on real hardware:
- Validate on a Mac: the CI job green, JIT exceptions under JITLink
(may need MachOPlatform/ORC runtime), Mutex under contention
(
__ulock),lldbstepping with-g, and Linux-cross-compiled objects linked and executed natively - A Homebrew formula (or tap) once native builds are validated
WebAssembly Target
- WebAssembly — also the cheapest route to an online playground, which is the most effective adoption funnel a new language has
Robotics Middleware
Robotics systems are dozens to hundreds of processes communicating over a DDS through a pub-sub middleware. Sun ships the message layer (native protobuf import); the transport is the gap.
- Custom DDS: discovery, topics, QoS, and a wire protocol
- Pub-sub middleware on top of it, with protobuf messages as the payload
- Interop with existing DDS implementations and ROS 2
Hardware Accelerators
Host Matrix<T> storage is complemented by optional NVIDIA-backed
cuda.DeviceMatrix<T> operations. General Sun-written kernels and asynchronous
device borrowing remain future work.
- Offload kernels via LLVM Offload
- Asynchronous device operations with lifetimes modelled by the borrow checker
- Validate the NVIDIA backend on ARM64 SBSA and Jetson hardware
Tuples (maybe)
Under consideration, not committed to.
- Tuple types:
(i32, string) - Tuple construction:
(1, "hello") - Destructuring:
var (x, y) = pair; - Multiple return values without a named class
Open Design Decisions
- FFI lifetimes: extern calls require an
unsafeblock, and the convention is a safe Sun wrapper around it. What remains undecided is whether the borrow checker should model a pointer escaping into C at all — todayref Thands C an address with no lifetime tracking across the call. - Generic instantiation: where do cross-module instantiations get emitted, and who owns deduplication — the compiler or the linker? (Today: use-site instantiation with link-time deduplication.)
- Memory model: should
Vec<T>own its allocator or take a reference? - Protobuf surface: import-only (
.protovia manifest) shipped first. A nativemessagedeclaration in Sun source withfield: T = tag;syntax remains open — it would drive the same source generator (ProtoImporter) from a parser production instead of aFileDescriptor.
Last updated: August 2026