2fcc1c287c
capabilities.md cited '== lowering to str_eq unless both operand names are in a hardcoded int-name set' as the paradigm defect. That is wrong: __int_names comes from type annotations, which is legitimate propagation. The real defect was 35 hardcoded builtin return types one layer down, and mislocating it hid a live miscompilation of unannotated lets. geometry-vs-code.md listed concurrency and error handling as open. Both are answered: ordering is a partial order and coordination is the price of forgetting; standing is signed, so not-known and known-false are opposite directions rather than one boolean. Added the fourth proof form (adversarial exactness) and recorded that form 1 no longer survives as a verdict -- every row it justified was a basis, not a capability. Also marked cross-cutting concerns as implemented rather than predicted.
143 lines
8.0 KiB
Markdown
143 lines
8.0 KiB
Markdown
# El — Capabilities
|
||
|
||
**What the language can do, stated as capabilities rather than as code.**
|
||
|
||
This list is the unit of analysis. Each entry gets one question — *prove this
|
||
cannot be done with pure geometry* — and the answer determines whether it stays a
|
||
capability of the language or collapses into the manifold.
|
||
|
||
Draft, 2026-08-17. Ordered roughly from most-likely-geometry to most-likely-code.
|
||
|
||
**Status after measurement.** The list was audited against the implementation
|
||
the same day. 28 entries collapsed to 19 geometry + 3 code: serialization, text
|
||
encoding, network and emission are all *projection onto a basis* (row 18) —
|
||
the convention is the basis, never the act. Storage collapsed because
|
||
persistence has no caller. Concurrency collapsed because coordination is the
|
||
price of forgetting, not a capability. A fourth proof form was added,
|
||
**adversarial exactness**, and form 1 stopped being a valid verdict.
|
||
|
||
**The table answers CAN only.** SHOULD and COST resolve per *site*, not per
|
||
capability — `is_digit` and `is_letter` are one capability with opposite
|
||
answers, and comparison spans three cost tiers. See the notes below.
|
||
|
||
---
|
||
|
||
## The list
|
||
|
||
| # | Capability | What it means | First read |
|
||
|---|---|---|---|
|
||
| 1 | **Comparison** | is this the same as that; is this greater | zero distance / sign of a displacement |
|
||
| 2 | **Ordering** | arrange by a criterion | position along an axis |
|
||
| 3 | **Containment** | is this inside that; does this contain that | region membership |
|
||
| 4 | **Correspondence** | where does this occur in that; how much of this is in that | a match-strength field over a span |
|
||
| 5 | **Segmentation** | divide a whole into parts | boundaries at measured discontinuity |
|
||
| 6 | **Composition** | join parts into a whole | adjacency; one position with parts |
|
||
| 7 | **Classification** | what kind of thing is this | which region does it land in |
|
||
| 8 | **Naming / binding** | attach a name to a thing and find it again | an edge; retrieval is projection |
|
||
| 9 | **Collection** | many things held together, indexed, counted | a set of positions; cardinality; projection onto the i-th |
|
||
| 10 | **Iteration** | do something for each of many | traversal |
|
||
| 11 | **Arithmetic** | quantity, magnitude, combination | displacement algebra on a line |
|
||
| 12 | **Time** | when; how long; how often | a 1-D affine space — instants are points, durations displacements, rhythms phases on a circle |
|
||
| 13 | **Identity** | which one is this; are these two the same one | coincidence of position |
|
||
| 14 | **Selection / dispatch** | choose which behaviour applies | nearest region |
|
||
| 15 | **Transformation** | produce a thing from a thing | change of basis |
|
||
| 16 | **Grounding** | how well is this supported | the weight on an edge. Has no caller |
|
||
| 17 | **Learning** | get better at something | standing changing over time |
|
||
| 18 | **Projection** | render meaning onto a surface | change of basis onto a surface basis |
|
||
| 19 | **Transduction** | take a signal in | change of basis from a sensor basis |
|
||
| 20 | **Serialization** | write a value as bytes someone else will read | **convention** — the format was agreed |
|
||
| 21 | **Text encoding** | what bytes mean which characters | **convention** — UTF-8, ASCII, case tables |
|
||
| 22 | **Storage** | keep a thing past this moment | durability against a device that loses power |
|
||
| 23 | **Network** | send a thing to another machine | wire protocol + socket |
|
||
| 24 | **Process** | start, stop, signal, exit | the OS boundary |
|
||
| 25 | **Concurrency** | more than one thing at once | hardware and OS scheduling |
|
||
| 26 | **Memory** | hold representations while they are in use | the substrate that holds positions |
|
||
| 27 | **Secrecy** | prove authorship; hide content; verify integrity | **structurally excluded** — see below |
|
||
| 28 | **Emission** | write the surface out as bytes | the physical boundary |
|
||
|
||
---
|
||
|
||
## Notes on the boundary cases
|
||
|
||
**27 — Secrecy is the one capability geometry cannot hold, and the proof is not
|
||
form 1.** A cryptographic hash is a *deliberately structure-destroying* map: its
|
||
entire value is that near inputs land at maximally uncorrelated outputs. Geometry
|
||
is the claim that near things stay near. A manifold that approximated SHA-256
|
||
would *be* a break of SHA-256. Signature verification is the same: 0.99-valid is
|
||
invalid. And X25519 *is* geometry — a group on an elliptic curve — which is
|
||
precisely why it must be code, because its security is the *hardness of moving in
|
||
that geometry*.
|
||
|
||
This is a fourth proof form and it should be added to `geometry-vs-code.md`:
|
||
**adversarial exactness.** Where approximation is a break, geometry is excluded.
|
||
|
||
**20, 21 — Serialization and text encoding are convention all the way down**, but
|
||
only at the *edge*. The byte format is agreed; what is being written is not. Do not
|
||
let a geometric computation inherit a code verdict because its result gets
|
||
serialized.
|
||
|
||
**11, 12 — Arithmetic and time are the same capability.** Instants are points,
|
||
durations are displacements, point−point→vector, point+vector→point. The runtime
|
||
already implements this correctly as `el_instant_add_dur` / `el_duration_add`. That
|
||
it *also* implements a five-entry string→multiplier table beside it (`time_add`
|
||
with `"ms"/"sec"/"min"/"hour"/"day"`) is the residue.
|
||
|
||
**7 — Classification is the most-violated capability in the codebase.** Seven ASCII
|
||
range tables (`is_letter`, `is_digit`, `is_alphanumeric`, `is_whitespace`,
|
||
`is_punctuation`, `is_uppercase`, `is_lowercase`) that return false for every
|
||
non-ASCII byte. `str_count_letters` reports zero letters for `é`. The wrongness on
|
||
most of Unicode is the tell that a table is standing in for a region.
|
||
|
||
**4 — Correspondence appears five times.** `str_index_of`, `str_index_of_all`,
|
||
`str_last_index_of`, `str_count`, `str_find_chars` are five projections of one
|
||
match-strength field: first zero, all zeros, last zero, count of zeros, first
|
||
class-crossing. One relation, five functions.
|
||
|
||
**14 — Selection is the crux for the compiler.** `+` dispatching on AST node kind
|
||
is selection-by-enumeration where selection-by-position belongs.
|
||
|
||
**Correction, 2026-08-17, from measurement.** This entry previously also cited
|
||
`==` lowering to `str_eq` "unless both operand names are in a hardcoded int-name
|
||
set — a literal list of variable names treated as integers." That is **wrong**.
|
||
`__int_names` is populated from *type annotations* (`param["type"] == "Int"`,
|
||
`let x: Int`), which is primitive but legitimate type propagation, not an
|
||
enumeration of blessed variable names.
|
||
|
||
The real defect was one layer down: `is_int_call` held **35 hardcoded builtin
|
||
return types**, the same shape as the 19 temporal ones. Those moved to
|
||
`lang/tools/check/signatures.rel`.
|
||
|
||
And the mischaracterisation hid a live bug. Because the return types were never
|
||
consulted at a *binding* site, an unannotated `let` lost its type:
|
||
|
||
```el
|
||
let a = str_len("hello") // no annotation
|
||
let b = str_len("hi")
|
||
let c = a + b // → el_str_concat(a, b) on two integers
|
||
```
|
||
|
||
That compiled clean, ran, and printed nothing where it should print 7 — no error
|
||
at any layer. Present in the pre-change compiler, so pre-existing. Fixed by
|
||
taking an unannotated `let`'s type from what its initialiser returns; the data
|
||
was already required for dispatch and simply never read there.
|
||
|
||
**The general lesson, since it recurred all session:** the enumeration was real
|
||
but I had located it in the wrong place. Naming a defect from reading is a
|
||
hypothesis. Eight hours of reading this file did not surface the miscompilation;
|
||
moving the data out and running the result did.
|
||
|
||
---
|
||
|
||
## What this list is for
|
||
|
||
Each capability gets audited **once**, across every place it appears — not once per
|
||
file. The output is not a percentage. It is:
|
||
|
||
- which capabilities survive the question and stay in the language
|
||
- which collapse into the manifold
|
||
- and for each one that collapses, **every site it currently appears at**, because
|
||
those sites are the residue and they are what gets deleted.
|
||
|
||
The line-count audit produced a map of where the residue sits. This produces a map
|
||
of **what it is**.
|