kailua
kailua copied to clipboard
Ignorable `_`
_
is traditionally used to denote an ignored argument/variable, and it frequently makes sense to have more than one:
function(_,_) return 0 end
So throwing
[Error] This variable will overwrite another same-named variable in the same scope
in this case is somewhat counterproductive.
I would've preferred to declare the function in question as function() return 0 end
in the first place, but that opens a whole new can of worms, since neither
(function(integer, integer) --> integer) | (function() --> integer)
nor
function(...:integer) --> integer
are valid types. And
function() --> integer
is not a subtype of
function(integer?, integer?) --> integer
either.
This turned out to be more difficult than I've originally thought. Originally I thought that this is a mere reporting issue because the type system doesn't care about the names and only the parser recognizes the "error", so I can just defer errors to see if the name is indeed used. But there is a catch: the type system has to assign types to every name even though it is never read again, so any fix to this issue can easily interfere with the type system.
In the current plan, the AST has to be able to mark some names "ignorable", which means that the name is never read (it's a fatal error if it does) and it gets exempted from the further type checking (except for the annotation itself, which should be a proper type). We do not make every unread names ignorable because we want to be notified for normal usages.