a, b, c Are WithdrawnStatus: Superseded by ADR-277 — its D1 is D2 there; D2 is not carried (the timing of the withdrawal, done)
Related: ADR-041 (which made naming the arguments the normal
form, carried these as experimental and warned about them; this completes it),
ADR-022 (the other lambda form this language withdrew, and the
precedent for withdrawing one), ADR-024 (NK1117, which is what
refuses the form now without a rule of its own).
A lambda could be written with no parameter list at all — fn { a.id } — and its
arguments were three fixed names, a, b, c.
The rule underneath it is the problem, not the spelling. How many arguments
such a lambda takes was read off which of the three names its body mentions.
So a local called a inside one was not a local: it was an argument, and a body
that wrote let c = … was asking for a third one.
ADR-041 made that visible: naming the arguments became the normal
form, the automatic names were carried as experimental, and NK1114 warned
wherever one was actually reached for. Visible is not the same as good. The rule
stayed true for exactly as long as the form existed, and every lambda in the
language depended on it.
fn { … } takes no arguments.A lambda’s arguments are the ones it names. A lambda that names none takes none,
which is the form .or_insert_with fn { Stats(0) } wants and has always meant.
Refused, not warned about. What goes with the form is the rule underneath it:
the arity-from-body mechanism, NK1114, and the one function the emitter and the
checker shared to compute it. Left in place they would keep the rule alive.
And it needs no refusal of its own. A body reaching for a is a body naming
something nothing declares, which is NK1117 — the check that exists because this
language has no word it does not know. So the withdrawal removes code and adds
none.
Announcing a withdrawal one release before making it is the procedure for a language with code in the world. There is no release and no Nikaia outside this repository, so a deprecation window protects nobody — and what it would do is keep both the rule and the warning alive for the length of the window.
Eight sites in four programs are rewritten, in two idioms: folding into a map
entry (.and_modify fn (stats) { stats.add(m.temp) }) and a sort key
(.sort_by_key fn (row) { -row.1 }). They had to be, since after this they do not
compile.
What it costs is a named argument where a letter used to do. That is the whole
of it, and the name is usually better: fn (stats) { stats.add(m.temp) } says
what is being added to.
The specification loses a form rather than gaining a warning. Part I 5.3 was two options with the second marked experimental; it is one form now, and the withdrawn one is described in a paragraph that says why.
Whether a short form should exist in future, in either direction. This is about these three names and the rule that came with them, not about brevity.
A count of the lambdas in this repository was offered as evidence for that question and is withdrawn as worthless: it omitted the parameter list from the comparison it was making, and twenty-one lambdas written by the language’s own authors say nothing about how anybody else would write.
All of it, and as a removal.
Expr::Closure has no implicit flag: the parser produces the same node for
fn { … } and fn () { … }, both with no parameters. emit::implicit_params —
the one function the emitter wrote its parameter list from and the checker asked
whether to warn — is gone, and so is check::warn_automatic_names and the
NK1114 code. The checker pushes the parameters a lambda names and nothing else,
so a body reaching for a meets NK1117.
NK1114’s number is retired rather than reused, and Part III C.3 says so: a
code that meant something in a published specification should not come back
meaning something else.
examples/1brc.nika, examples/access-log/src/main.nika, examples/k-nucleotide/src/main.nika
and examples/inventory/src/main.nika name their lambda arguments, as do the
specification’s own examples.