Status: Superseded by ADR-277 — its D1, as completed by ADR-049 D1, is D2 there; D2 is not carried (withdrawn by ADR-049 D1), nor D3 (the one-time rewrite of the corpus) Related: ADR-049 D1 (the withdrawal this record set up), ADR-022 D1 (one lambda form with two spellings — amended in which of the two is recommended, and in nothing else), ADR-018 D1 (the HTTP handler’s implicit first argument, which D3 leaves alone and why), ADR-010 D1 (the polarity D2 follows in choosing what to warn about).
A block lambda has two spellings of one form: fn { … }, whose arguments are
named automatically a, b, c, and fn(user) { … }, where they are written
down. Both parse everywhere.
The automatic spelling carries a rule that is not visible in it: how many
arguments the lambda takes is read off which of the three names its body
mentions. So a local called a inside such a lambda is not a local — it is an
argument, and the closure’s arity stops matching its call. The specification said
so and told the reader to use the named spelling where a local wants one of those
names; examples/access-log/src/main.nika carried a comment warning its own future reader
off c for exactly this reason.
The automatic naming was criticised in review. That is the occasion for this
record rather than its argument, and the argument is the one the criticism points
at: while fn { … } is the recommended spelling, every lambda in the corpus
depends on the automatic rule, so the rule cannot be changed later without
breaking all of them. Making the named spelling the normal one is what buys the
freedom to change the automatic one at all — including withdrawing it.
fn(name) { … } is what a lambda looks like.Part I 5.3’s two options swap places: the named one is Option A and is described first, and the automatic one is Option B and described as experimental.
This amends ADR-022 D1 in one respect and leaves the rest standing. There is still one lambda form with two spellings, both still parse, and both still go in all the same places. What changes is which of the two the specification teaches.
NK1114, severity warning: the program compiles. The help is the mechanical
rewrite — the same letters in a parameter list — because that is the step that
matters: after it the count is written down instead of read off the body, and
renaming to something that says what the argument is becomes an ordinary edit.
A fn { … } that reaches for none of the three is not warned about. The form
is not being withdrawn; the automatic naming is. A warning there would fire
where no parameter is generated, which is a warning about nothing.
So the question the warning asks is exactly the question the emitter asks to
write the parameter list, and it is asked of the same function in the same
place. Two copies of “which of a, b, c does this body mention” would drift
into a warning that fires where no parameter is generated, or the reverse.
While the specification’s own examples use the automatic spelling it teaches what
it advises against, and while the corpus uses it the warning fires on this
project’s own programs. Both are rewritten with names that say what the argument
is — six sites in four example programs, and every example in Parts I–III — and
examples/access-log/src/main.nika loses the comment that warned its reader off c,
because the trap is gone rather than documented.
Two sites keep the automatic spelling deliberately: Part I 5.3’s own example of
Option B, and its Status note’s list of what parses. Both are about the
spelling.
ADR-018 D1 is untouched. The HTTP handler is a lambda taking
the request as its first implicit argument, and fn { "Hello World" } — the
canonical handler — mentions none of the three names, so it is not warned about.
A handler that does reach for the request is warned about like any other lambda,
and Part III’s example now names it.
What this amends. ADR-022 D1, in which spelling is recommended and in nothing else.
What it does not decide. Whether the automatic naming is eventually withdrawn. That is the freedom D1 buys and not a decision taken here: withdrawing it would be its own record, and it is only possible at all once the normal form does not depend on it.
The warning’s position is the statement’s, not the lambda’s. An expression carries no span of its own, so a statement holding two such lambdas is warned about twice at the same place. That is noisier than it is wrong, and it is the same limit every expression-level diagnostic in this compiler has.
D1, D2 and D3 are built. NK1114 is raised by the type checker from
emit::implicit_params — the one function that decides which automatic names a
body reaches for, shared with the emitter so the warning and the parameter list
cannot disagree. Part I 5.2, 5.3 and its Status note, Part II 12.1, 12.2 and
12.6, Part III 13.5 and 17.1, and six sites in four examples/ programs are
rewritten.
What is not built is anything that removes the automatic spelling: it still parses, still lowers, and still means what it meant.