Known limitations — v0.5.0-beta.1
This list describes the Java stage-0 implementation, not every feature proposed by the historical design kit in docs/history/design-kit/.
- The compiler is written in Java and emits Java source before invoking
javac. It does not compile itself and is not self-hosted. conform C to Jis v1-scoped: Java interfaces only, a non-generic source class and target interface, no overloaded abstract methods and no method renaming or adapters. It declares a foreign JVM contract; it does not add inheritance or interfaces to the language. Generic methods witness by erasure; boxedShort/Byte/Characterparameters are not expressible because of the existing interop adapters.- Generics accept one or more parameters (
generic K, V:) but are fully explicit: no inference, no variance, and partial type arguments are never guessed. A type parameterThas no operators, ordering or methods, and equality only underrequires T: Equatable;Comparableand user-defined capabilities are not implemented (SPR-GENERIC-CONSTRAINT). - Generic code is erased and boxed in generated Java (type parameters become
Object). Boxing/unboxing is compiler-controlled, but generic values carry no JVM-level type information at runtime. - Local/Git Sprig and Maven JVM dependencies are resolved by
sprig resolve,sprig addandsprig remove. Schema-4 locks verify graph identity, manifests, owner-relative locators and JAR/POM SHA-256. Shared project classpaths work for check/build/run/api/doctor; only explicit dependency-resolution commands use Maven networking. Apache Resolver handles effective POMs and mediation. Missing/invalid POMs fail. Publishing/registry, authentication, Maven plugins and non-JAR runtime artifacts remain unsupported. SeeDEPENDENCIES.md. - The small
std/slice covers UTF-8 filesystem/path, arguments/environment, text/time and a typed JSON model. The first-partysprig-httplibrary adds a small synchronous JDK HTTP client; it does not provide an HTTP server, streaming, async requests or a stable package registry. The ecosystem remains intentionally small and experimental. LSP, debugger integration and incremental compilation are absent. The local VS Code preview offers lexical highlighting, CLI checks/run and Java viewing; seeeditors/vscode/README.md. - JVM interop covers common imported classes, constructors, fields, method calls, overloads, and checked exceptions. Java arrays cross the boundary as opaque values (no source array syntax; varargs remain unsupported). Concrete generic arguments are preserved for explicit
Type[Arg]application on imported classes and methods; wildcards, inference, recursive and intersection bounds, generic arrays and Short/Byte/Character generic arguments are rejected with structured reasons, class bounds are validated, raw evidence never promotes to concrete arguments, and raw boundaries stay erased. Collection conversion is explicit through@std/jvm.spr; there is no implicit Java/Sprig collection conversion. Type-use nullability annotations are not interpreted. Java reference results are conservatively nullable; Java reference parameters are conservatively non-null. - Sprig
throwsandcatchare implemented, but their relationship to Java exception classes and top-level execution remains provisional. - Lambdas have single-expression bodies, support arities zero through three, and cannot declare a
throwstype. A lambda that calls a checked-throwing operation must handle that effect inside the lambda. - Runtime numeric failures report
SPR-RUNTIME-EXCEPTIONwith the nearest statement range for local and importedInt/Int32checked arithmetic, plusdata.origin="checked-arithmetic"; the span is the statement, not a sub-expression. JVM library operations do not inherit Sprig's checked integer arithmetic rules. - Floating-point operations follow Java
float/doublebehavior. The compiler does not promise cross-JVM bitwise identity for transcendental functions, numerical stability, physical units, or mathematically correct algorithms. - Compiler classes use
javac --release 17. Supported release platforms are Linux/macOS with JDK 17 and 26; Windows is an experimental, non-blocking preview; definitions are not execution evidence. The current release validation report records which exact source/archive gates ran. No production or architecture-wide portability guarantee is made. - Portable local locks carry owner-relative locators and survive relocation of the whole workspace; absolute-path declarations are not portable and need
resolveafter the target moves. The lock does not attest source bytes or symlink targets. It also does not pin bundled@stdbytes:@stdcomes from the installed SDK, whose published archive is checked separately through release checksums and extracted-archive smoke tests. Manifest semantic errors can point to line 1. Cache tree verification adds IO; OS locks have no timeout. Git submodules are unsupported. Offline Git builds require Git and a complete verified cache. Concurrent hostile mutation after validation is outside the cooperative cache model. sprig fmtis canonical and comment-preserving, without configuration or aggressive wrapping. See formatter for file safety and comment indentation policy. LSP integration remains future work.sprig testis a sequential project runner for ordinary.sprprograms. It has a fixed 30-second runtime timeout and no parallel execution, watch mode, coverage, snapshots or test-function discovery. It requires a current lockfile and checks negative fixtures by diagnostic code, not message. See testing for its JSON and temporary directory contracts.tests/agent_evalprovides deterministic fixtures and scoring only. No LLM run has been performed, and no model performance is claimed.- The managed SDK installer/upgrader is supported only on Linux/macOS and targets public GitHub releases. Published SHA-256 assets detect archive mismatch but do not provide signed provenance. Older SDKs are retained. SQLite migrations record filenames without content digests; changing an applied migration is unsupported by convention, not automatically detected. Migration SQL is trusted project code.
- The stage-1 frontend is a subset probe, not a self-hosted compiler.
- Sprig targets v0.5.0-beta.1, an experimental Beta under Apache-2.0 (
LICENSE,NOTICE), not a production stability or numerical correctness guarantee.
Callable boundary
Source function types now use fn(A) -> R, arities 0–3. Parameters and results are invariant. Callable types carry no recoverable throws effects: handle those inside named wrappers before placing them in a lambda. Arbitrary Java SAM interfaces are not converted. Only concrete Fn0..Fn3 generic signatures preserve callable types; raw, wildcard or unresolved type variables are rejected. Character/Short/Byte callable slots and arbitrary parameterized Java slots are unsupported because they would require additional erased-value adapters. Nullable callable values use (fn(A) -> R)?; fn(A) -> R? means nullable result.
Project discovery currently compares normalized source-root prefixes rather than canonicalizing alternate symlink spellings. On macOS an explicit absolute /var source while cwd discovers /private/var can be treated as standalone and lose package aliases. Use project-relative source paths from the project directory; this existing path-alias behavior was reproduced during the SDK web experiment.
