Philosophy
The root mental models from which everything derives. They were fixed before the syntax, because coherent syntax is not designed keyword by keyword.
The idea
Section titled “The idea”Most languages grow by accretion: match is decided today, pointers next week, declaration
later. They are three local decisions that do not talk to each other, and the result is a patchwork
where each new concept never quite fits. Makoto inverted the order: define the cross-cutting
principles first, and let each construct fall almost by itself from them.
How Makoto redefines it
Section titled “How Makoto redefines it”There is a hierarchy of principles, from the most applied to the most general:
- Opt-in test (the metric): you only pay for what you summon. A concept is expensive if those who do not
use it need to understand it. From there follows the corollary: the default is always the unmarked one. Private is
bare,
pubis the mark; immutable is the bare:=,varis the mark; safe is the normal,unsafeis the mark. This is not a separate principle; it is opt-in applied to each axis. - Non-poisoning (the local application): each subsystem carries only its own colors. The memory interfaces do not say which memory; IO does not say sync/async; the global namespace carries no function at all. A subsystem cannot “poison” the others by leaking its details.
- Systems-and-boundaries / tainted coloring (the general law): the one that governs the two above. Every color belongs to a realm; the sin is the color of one realm staining another. “Poisoning” is just the name of that stain seen from inside.
And two form rules that fall out of these principles:
- Unification by concept. When N keywords exercise the same verb on different objects, they become
one.
switch/match/selectmatch(the object disambiguates);for/while/infinite-looploop. But, and this is the fine point, “same verb” means same operation and same realm, not same form.struct,enumandinterfacehave bodies of different shape and still unify underdecl, because they are the same act (declaring a type) in the same realm (the type system).unionhas a body identical to a struct’s and still does not unify, because it is another operation (reinterpreting bytes) in another realm (the unsafe one). Unifying by surface similarity would be committing sin #3 itself. - Axes are preserved, not fused.
let/var/constlook like “three forms of declaring”, but they are a mutability axis with a default. Fusing them into abind(mode=mut)would erase the axis: the distinct names are the visual information, not noise. The rule: if it is one act with different objects, unify; if it is one act with an axis-of-modes, preserve the axis.
And the architecture that all of this projects onto the ecosystem: the tiers (ch. 11), with layered stability, the add-only core at the bottom and what changes faster living higher up.
The reasoning
Section titled “The reasoning”The principles are not aesthetics; they are a decision machine. When a proposal arrives (“what if we
gave a separate keyword for each way to import?”), it is tested against the principles instead of
taste. The answer was to unify everything under use (importing is a single act): it is the form after the
keyword that carries the intent. use json qualifies (json.parse), use json.{parse} lifts the
name (parse), use json as j aliases. One keyword, three intents in the syntax, without three words. And
when the principle predicts a choice you had already made by instinct (private-bare, UTC-in-core
and IANA-opt-in), it is a sign that the principle is real, not imposed.
Why not the alternatives
Section titled “Why not the alternatives”- Why not design keyword by keyword? Because it generates inconsistency: local decisions that do not talk to each other. Principles first is what gives few keywords and coherence at the same time.
- Why not unify everything that looks alike (
struct/interfaceunder a singletype)? Because it would erase the boundary between data and dispatch, exactly what law #3 forbids. The form deceives; what counts is operation + realm. - Why not convention (capitalization = public, à la Go)? Because scope should not depend on attention-dependent convention; it should be an explicit mark. It is opt-in applied to visibility.
The concrete pain
Section titled “The concrete pain”Without explicit principles, the raw count of decorators is scary; “so many loose decorators?” looks like chaos.
Reorganized, they are the index of 4 to 5 subsystems (@mm is memory; @supervisor/@transfer
are concurrency; @cimport/@asm are FFI). The raw count is noise; grouped by system, it is
organization. The principle is what turns “an arbitrary list” into “a map”.
The mental model
Section titled “The mental model”The default is the unmarked one; you mark when you leave the common case. And one unifies by operation + realm, never by form.
The accepted friction
Section titled “The accepted friction”The discipline costs consolidation. You cannot simplify struct/interface into a single keyword,
even when it looks tempting, because it violates the boundary. The @ sigil ends up indexing 6 to 7 subsystems
(visually denser than a handful of keywords would be), and the axes demand distinct names (let,
var, const) instead of a parameterized construct. In every case the choice was conceptual
clarity over surface economy: more symbols, but each one is a signal.
Next: 02 · Memory