Design Principles

Calor is built on five core principles that guide every language design decision. These principles serve a deeper goal: enabling verification. Every design choice makes contracts and effects machine-checkable, not just human-readable.


The Five Principles

PrincipleImplementationAgent Benefit
Explicit over implicitEffects declared with §E{cw,fs:r,net:rw}Know side effects without reading implementation
Contracts are codeFirst-class §Q (requires) and §S (ensures)Generate tests from specs, verify correctness
Everything has an ID§F{f001:Main}, §L{l001:i:1:100:1}Precise references that survive refactoring
Unambiguous structureMatched tags §F{}...§/F{}Parse without semantic analysis
Machine-readable semanticsLisp-style operators (+ a b)Symbolic manipulation without text parsing

1. Explicit Over Implicit

In traditional languages, side effects are implicit. You have to read the entire function body to know if it:

  • Writes to console
  • Reads from files
  • Makes network calls
  • Accesses a database

Calor requires explicit effect declarations:

Plain Text
§F{f001:SaveUser:pub}
  §I{User:user}
  §O{bool}
  §E{db:rw,net:rw}        // Explicit: database and network effects
  // ... implementation
§/F{f001}

Agent benefit: An agent can immediately filter functions by their effects without analyzing implementation details.

Effect Codes

CodeEffect
cwConsole write
crConsole read
fs:wFilesystem write
fs:rFilesystem read
fs:rwFilesystem read/write
net:rNetwork read
net:wNetwork write
net:rwNetwork read/write
db:rDatabase read
db:wDatabase write
db:rwDatabase read/write

2. Contracts Are Code

Preconditions and postconditions aren't comments or assertions buried in code - they're first-class syntax elements:

Plain Text
§F{f001:Divide:pub}
  §I{i32:a}
  §I{i32:b}
  §O{i32}
  §Q (!= b 0)              // Requires: b is not zero
  §Q (>= a 0)              // Requires: a is non-negative
  §S (>= result 0)         // Ensures: result is non-negative
  §R (/ a b)
§/F{f001}

Agent benefit:

  • Automatic test generation from contracts
  • Static verification of caller sites
  • Clear documentation of function behavior

Contract Syntax

TagPurposeExample
§QPrecondition (requires)§Q (> x 0)
§SPostcondition (ensures)§S (!= result null)
§Q{message="..."}With custom error§Q{message="x must be positive"} (> x 0)

3. Everything Has an ID

Every structural element has a unique identifier that persists across refactoring:

Plain Text
§M{m001:Calculator}           // Module ID: m001
§F{f001:Add:pub}              // Function ID: f001
  §L{for1:i:1:100:1}          // Loop ID: for1
    §IF{if1} (> i 50)         // Conditional ID: if1
    // ...
    §/I{if1}
  §/L{for1}
§/F{f001}
§/M{m001}

Agent benefit:

  • "Edit function f001" is unambiguous
  • IDs survive code movement and renaming
  • No reliance on line numbers that change

ID Conventions

Production code uses ULID-based IDs with kind prefixes:

ElementPrefixExample
Modulesm_§M{m_01J5X7K9M2NPQRSTABWXYZ12:Calculator}
Functionsf_§F{f_01J5X7K9M2NPQRSTABWXYZ12:Add:pub}
Classesc_§CL{c_01J5X7K9M2NPQRSTABWXYZ12:MyClass}
Methodsmt_§MT{mt_01J5X7K9M2NPQRSTABWXYZ12:Process:pub}

Short test IDs (f001, m001) are allowed only in tests/, docs/, and examples.

Learn more: Stable Identifiers - Why IDs matter and how challenges are overcome


4. Unambiguous Structure

Every opening tag has a matching closing tag with the same ID:

Plain Text
§M{m001:Example}
  §F{f001:Main:pub}
    §L{for1:i:1:10:1}
      §IF{if1} (> i 5)
        // ...
      §/I{if1}
    §/L{for1}
  §/F{f001}
§/M{m001}

Agent benefit:

  • No brace-counting ambiguity
  • Parse structure without understanding semantics
  • Easy to verify structural correctness

Closing Tag Rules

OpeningClosing
§M{id:name}§/M{id}
§F{id:name:vis}§/F{id}
§L{id:var:from:to:step}§/L{id}
§IF{id} condition§/I{id}

5. Machine-Readable Semantics

Expressions use Lisp-style prefix notation that's directly manipulable:

Plain Text
// Calor: Clear AST structure
(+ (* a b) (- c d))

// Equivalent infix: Requires precedence parsing
a * b + c - d     // Wait, is this (a*b)+(c-d) or a*(b+c)-d?

Agent benefit:

  • No operator precedence ambiguity
  • Direct AST manipulation
  • Symbolic computation without parsing

Operators

CategoryOperators
Arithmetic+, -, *, /, %
Comparison==, !=, <, <=, >, >=
Logical&&, ||, !

Principle Interactions

These principles reinforce each other:

  1. IDs + Closing tags = Unambiguous scope references
  2. Contracts + Explicit effects = Complete behavioral specification
  3. Lisp syntax + Contracts = Symbolic verification possible
  4. IDs + Contracts = Traceable invariants across refactoring

Next