LilScript is an independent statically typed language. .lil is never parsed as JavaScript or TypeScript. JavaScript and native object code are backends of one typed whole-program IR.
Parent: Mission. Contract: docs/language-v0.1.md.
Durable rationale: typed proofs, not glue,
representation and ABI.
Every surface construct is judged by whether it gives the compiler a proof it can use for DCE, layout, mangling, or codec search — without introducing TypeScript-style glue (erased types, implicit any, structural holes at npm boundaries, runtime wrappers).
| Construct | Proof it gives the compiler |
|---|---|
Nominal struct / class |
Field indexes; scalar replacement; no property names internally |
Named object |
ABI keys on one singleton identity; private method bodies nest/mangle |
object { ... } |
Ordinary-prototype JS dictionary; inherited hooks remain observable |
Record<T> |
Open string keys are data, never mangled |
Closed enum + match |
Integer discriminant, no metadata object; exhaustive DCE of arms |
extern / extern class |
Exact host ABI by default; everything else may dissolve |
T? and A | B |
Narrowing without wrappers; native tags only at boundaries |
pure / inferred effects |
Unused calls are removable |
| Static imports | Cross-file SSA; module syntax is not emitted |
import("./x") |
Typed lazy chunk; lazy modules are init-free |
int vs number |
Proven-safe ` |
JsValue |
Narrow dynamic hatch; native rejects it |
- Types are not glue
- Compressor surface — write proofs so Terser/Oxc/Closure can lose
- Numerics and value semantics
- Aggregates — struct / class / record
- Collections and typed intrinsics
- Async, generators, and regex
- Closed world
- Packages, exports, and ABI
- Boundaries and escape
- Modules, lazy loading, progressive enhancement
- JavaScript vs native
Language design is upstream of compilation. If a feature cannot be checked, escaped, and represented, the compressor cannot legally rewrite it. Prefer a smaller, explicit surface over a JS convenience that would force conservative lowering. Whether a legal representation is then searched or hard-wired is decision registry. How to write a port so Terser/Oxc/Closure can lose: compressor surface.
Config that changes language-visible ABI must be normalized into the compilation contract, not treated as a codec preference:
javascript.public_aggregate_abi— named fields vs positional handles at the reusable JS boundaryjavascript.aggregate_layout— named objects vs positional arrays for instancesjavascript.function_spelling— legacy combined public/private callable policy[mangle] exports/properties— public names vs owned fields[bundle] mode— artifact/module layout, distinct from application vs library world