dart-lang / dart-lang/language
NNBD, non-nullable named parameters with defaults, and wrapping.
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
## Problem statement
With NNBD we will now have static checking that non-nullable named parameters can never contain null, which is great generally :tada:.
This does present a problem however when trying to wrap a function with non-nullable optional named parameters that have default values, especially if you want those same named parameters in your own function.
Here are a couple examples of how you could do this with NNBD as it stands now:
```dart
void original({int a: 0, int b: 1}) {}
void wrappedWithExplicitChecks({int? a, int? b}) {
if (a != null) {
if (b != null) {
return original(a: a, b: b);
} else {
return original(a: a);
}
} else if (b != null) {
return original(b: b);
} else {
original(a: a, b: b);
}
}
void wrappedWithCopiedDefaults({int a: 0, int b: 1}) => original(a: a, b: b);
```
Neither of these are satisfactory:
- in the first example the number of conditions quickly explodes to the point that it is unreasonable even with just 2 arguments.
- in the second example you are forced to copy the defaults which is slightly annoying, but more importantly it could lead to accidental breakage if the underlying default changes.
## Proposed solution
Credit to @jodinathan for the original idea here (from gitter).
Allow `default` as a value for named arguments. This would be compile time syntactic sugar only and would translate to copying the value of the default from the underlying named parameter. If the default value is not statically known then it would be a static error to use `default`.
`default` is already a reserved word (so it can be used in switch statements) so there should be no concern with using that name.
Example usage:
```dart
void original({int a: 0, int b: 1}) {}
void wrappedWithDefault({int? a, int? b}) => original(a: a ?? default, b: b ?? default);
```
**Pros**:
- scales linearly based on the number of named arguments
- relatively minimal boilerplate involved
- relatively minimal complexity overhead
- can likely be implemented only in the CFE
- low risk
**Cons**:
- you still end up having to make all your named arguments nullable, and do explicit null checks
- it doesn't work for all cases, only ones where the default is statically known
Contributor guide
Assessment
This issue has not been assessed yet.