Skip to main content

The order

Sense’s design follows an explicit sequence, and it is emphatic that classes and syntax do not come first:
1

1–3. Computational model, execution model, state/context/session

2

4. Deterministic computation

3

5. Probabilistic computation

4

6. Agent model

5

7. Capabilities and policies

6

8. Memory

7

9. Verification

8

10–11. Type system, effect system

9

12. Evaluate OOP

10

13. Syntax

11

14. Compiler/runtime implementation

Syntax is second-to-last. This is not an accident or a stylistic preference — it’s a guard rail against a specific, common failure mode in language design: letting whatever’s easiest to parse quietly become the semantics, because the parser gets written before anyone has actually decided what the language is supposed to mean.

What happens when you skip it

Sense’s own history has a concrete example, worth being honest about rather than glossing over. The implementation’s first two phases shipped with fn, let, { } blocks, -> for return types, and &&/||/! — a fairly conventional C-family-meets-Python syntax. It worked. It also turned out to be exactly the mistake the design order exists to prevent: that syntax was picked by default, for parser convenience, before anyone had actually weighed it against what Sense is supposed to be — a language simpler than Python, readable by people with no formal programming background, and easy for an LLM to generate correctly. A C-family syntax grafted onto Python’s shape wasn’t a decision toward that goal; it was the path of least resistance. The fix was a full grammar rewrite: indentation-based blocks instead of braces, no fn/let at all, returns instead of ->, and/or/not instead of symbols. Semantics were untouched — every AST node, every runtime behavior, stayed exactly the same; only how source text gets turned into that AST changed. That’s the direct, practical payoff of deciding semantics before syntax: when syntax turned out to be wrong, fixing it was a bounded, mechanical, surface-level rewrite, not a redesign of what the language actually does.
The lesson generalizes past this one incident: any language (or any feature within one) that lets its concrete syntax get decided before its semantics are settled is taking on exactly this risk — a rewrite that could have been a discussion instead.
Plain function declarations later moved back to def/-> specifically — see Functions — but that’s not a quiet reversal of this lesson. It was a separate, deliberate, narrowly-scoped decision made after weighing the actual tradeoff (a plain function carries none of the capability/safety/agency semantics that motivate the rest of Sense’s syntax reading differently from Python), not syntax settled ahead of semantics by default. Every other declaration — tool/action/agent/… — kept the house style established here.

Why this matters for how Sense keeps getting built

Every phase of Sense’s implementation follows the same discipline as a consequence: build the smallest honest slice of a concept — one with no unmet dependencies — rather than the full feature list a design doc describes, and write down explicitly what was deliberately left out and why. model/ask/answer shipped before agent, agent shipped before tool, action’s prepare→verify→commit shipped before approval gates or audit logs. In each case the missing pieces are visible in the Roadmap as reasoned omissions, not silent gaps — because a keyword that exists but doesn’t yet mean anything real is a worse outcome than a keyword that doesn’t exist yet.

Continue

Non-goals

The explicit test for whether Sense is pulling its own weight as a language.

Roadmap

What’s built, what’s deliberately deferred, and why — phase by phase.