Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Design Decisions That Matter

Every language has a handful of decisions that shape everything downstream. For Lykn, these were:

S-Expressions as Syntax

The reader is trivial (~320 lines) because s-expressions have no syntactic ambiguity. Macros are natural because code is data. The trade-off: parentheses, and the cultural resistance they provoke. Every developer who sees (+ 1 2) for the first time has the same reaction.

JavaScript as the Target

ESTree provides a well-specified IR. astring (JS) and the Rust codegen provide pretty-printers. The JS ecosystem provides the runtime, the package registry, the deployment infrastructure. The trade-off: inheriting JavaScript’s semantics — floating-point only, typeof null === "object", the coercion table.

Two-Layer Architecture

Kernel maps 1:1 to JavaScript. Surface adds safety. The kernel never changes for surface features. The trade-off: two compilers to maintain, and the surface must express everything in terms of kernel forms. But changes to match never break const emission.

Required Type Annotations

Every parameter, every constructor field. :any is the opt-out. The trade-off: more typing (literally). But every boundary is checked, and the runtime cost strips in production.

Immutability by Default

bind is const. Mutation requires cell. The trade-off: cell/express/swap! ceremony for every mutable value. But every mutation point has ! — visible, greppable, intentional.

No this

The trade-off: classes are kernel passthrough. OOP patterns require dropping to kernel syntax. But the entire this-binding hazard category is eliminated.

Each decision has a trade-off. The book has been teaching the decisions. This section names the trade-offs honestly.