Description
If I compile something like
void p({int a}) {
...
}
the compiler complains that The parameter 'a' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
, while it should simply understand that the named parameter a
is required.
Proposal
A formal named parameter that has a non-nullable type and no default value, should be understood as being mandatory. I am surprised that no one has already asked for that (at least I did not find a relevant issue).
The required
keyword can make a difference only in the case of a formal named parameter without a default value, but which has a nullable type. Specifically, it would force the caller to actually send null
as a value instead of not specifying a value at all for the parameter. But that's hardly programmer-friendly so I deem the required
keyword should be removed from the language.
Activity
lrhn commentedon May 2, 2025
That would create a difference between function declarations and function types.
It would also affect forwarding constructors.
It would require a way to specify that one of
C.fwdReq
andC.fwdOpt
has a required parameter and the other an optional parameter. Therequired
keyword does that today.When you say "non-nullable type", that means that generic functions can have parameters that are optional depending on the type argument.
Or does it use the declared type, not the actual parameter type, which in this case is the type parameter
T
which is not nullable (nor is it non-nullable, it's potentially either).I'm not unsympathetic to doing something here, but it's not as easy as this.
(Related issues include at least #1639 and #2232, where the latter tries to formalize precisely this "nullable means optional"/"null means no argument" approach.)
acarstoiu commentedon May 2, 2025
I'm missing something here, why doesn't the
IntEater
type also contain the compulsoriness ofvalue
?As they are written, both forwarding constructors have
a
as required parameter. To preserve the behaviour ofC.opt
, one should definefactory C.fwdOpt({int? a}) = C.opt
.That's because if a formal parameter's type is non-nullable, then its default value should be used when the function is called with
null
as the parameter's value.Yes, precisely.
acarstoiu commentedon May 2, 2025
Read a bit some messages on those threads. You're an advocate of the equivalency between "null actual value" and "no actual value" getting passed to a function.
But, since in Dart there's the notion of nullable type, I strongly believe "null actual value" and "no actual value" are to be treated alike only when the declared parameter type is non-nullable. That's just to allow the programmers do their own design, whether you consider it poor or not.
If the type is nullable, then the function body should expect to receive a
null
for the parameter's value, regardless of the presence of a default value in the declaration. In this case, the syntactic sugar proposed in this comment should be enough to promote the parameter's type to non-nullable inside the function's body.mateusfccp commentedon May 2, 2025
There are at least two issues similar to this one. One of them was opened during the null-safety development, and was closed.
The other is still open and IIRC is slightly different but on the same line.
GitHub's search is just terrible.
Edit:
Found one of them, #878.