dart-lang / dart-lang/language

NNBD, non-nullable named parameters with defaults, and wrapping.

Open
#577 15 comments 4 reactions 0 assignees View on GitHub
feature
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.