Luce / engineering
Learn Luce LuciaOS

The decisions that shape Luce

Why do integers trap instead of wrap? Why do workers copy instead of share? Why are structs and classes separate? These are not isolated preferences; each one simplifies several later parts of the compiler and runtime.

Load-bearing principles

The architecture in four arrows

apps → luce moduleproducts consume the language through its public compiler/runtime surface
specs → both pathsprogram behavior is never proved on only one execution implementation
both paths → runtimeARC and dynamic semantics have one body
artifact → host tablenative code touches the world only through an explicit versioned capability interface

Before 1.0, remove old designs cleanly

Luce does not promise source compatibility before 1.0. A better spelling or model changes the tree coherently; deleted names do not remain as deprecated aliases. Serialized MIR and native ABI versions exist to reject stale artifacts safely, not to translate them.

Compatibility and correctness are different jobs. A stale cache can recompile. Preserving two meanings for one pre-release feature would make every later stage and document carry permanent branching complexity.

Mechanisms deliberately absent

No VM fallback, duplicated runtime, implicit numeric promotion, class inheritance, shared worker heap, manual memory API, tracing collector, mutable global state, reflection, or macros currently sits behind the surface. A future feature must earn its mechanism with a real customer and a complete acceptance matrix.

Current truth, plans, and history

Current references describe code that exists. Plans use non-compilable text for syntax not implemented yet. Decision records preserve only boundaries whose history remains useful. Keeping these categories separate prevents an intended feature from being mistaken for a language promise.