A type variable is marked, because absence is a bad thing to give meaning to
This commit is contained in:
parent
97cb77d949
commit
7be57efe18
34
NEXT.md
34
NEXT.md
@ -1,3 +1,37 @@
|
||||
## Decided by the author, 2026-09-13: a type variable takes a `$` sigil
|
||||
|
||||
**This overrides plan.org**, which says under Types: *"Lowercase type names are variables, Capitalized are
|
||||
concrete — no sigil."* That rule is withdrawn. Taken as provisional, to make progress rather than as a final
|
||||
design, and expected to be revisited after some real use.
|
||||
|
||||
```lisp
|
||||
(defn swap [xs [$t] i i32 j i32] () ...)
|
||||
```
|
||||
|
||||
Three reasons, the third being the one that actually forced it.
|
||||
|
||||
1. **There is no binding site without a sigil.** Nothing distinguishes where a variable is introduced from where
|
||||
it is used.
|
||||
2. **Introducing one is invisible.** `check.ml:535-562` resolves builtins, aliases, structs, unions, enums, then
|
||||
near-miss, and *then* treats any leftover lowercase name as a type variable. So a lowercase name nobody has
|
||||
heard of silently becomes a type parameter, and a mistyped type makes the function **more** permissive instead
|
||||
of failing. The `near_miss` guard at line 553 exists for exactly this hazard and only reaches names close to a
|
||||
known one — the comment there says so. `[elem]` is not close to anything and would become generic silently.
|
||||
3. **Brackets carry two opposite rules for the same lexical thing.** In `[n t]`, `check.ml:563` resolves `n`
|
||||
against `env.consts` and *errors* if it is absent, while `t` becomes a *variable* if absent. Absence means
|
||||
"mistake" on one side of the bracket and "new parameter" on the other.
|
||||
|
||||
The rule is also not the one plan.org states. It is not case-based: `i32`, `f32`, `bool` and `string` are all
|
||||
lowercase and concrete. What the code actually does is **treat any unresolved lowercase name as a variable**,
|
||||
which is an absence rule, and absence is a bad thing to give meaning to.
|
||||
|
||||
**Open, and deliberately not decided here:** whether a *use* after the binding is `$t` or bare `t`. Odin binds with
|
||||
`$T` and uses bare `T`. Left to whoever builds it, to be reported with the reason.
|
||||
|
||||
**Also open: `$n` in length position**, Odin's `$N: int`, which is what would make a function generic over array
|
||||
length rather than only element type. Not in the spike unless it falls out for free; the spike is to report what it
|
||||
would cost.
|
||||
|
||||
## To discuss: five gaps the raylib examples hit and could not close
|
||||
|
||||
Found by the lane that ported `core-2d-camera`, `core-scissor-test`, `core-window-flags`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user