-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Solution: Make a parameter optional by giving it a default value #16
Comments
We would need really really strong evidence that this is a problem to justify a breaking change of this magnitude... |
@Hixie I agree if you see this solution as independent of any other breaking changes. But I think other breaking changes are suggested such as types that are non nullable by default. If this will happen, there will probably be some codemod released to migrate code to Dart 3 in a non breaking way. If we already have to migrate code to Dart 3, I don't see a reason to also include an automatic fix in the codemod for this proposal. |
Non-nullable types (by default, or otherwise) would basically allow your change "for free". Consider: void main() {
// Compile-time error: `a` is non-nullable but no value was passed.
method();
// Compile-time error: `a` is non-nullable.
method(a: null);
// OK.
method(a: 5);
}
void method(
a,
// Nullable
b?,
) {
// ...
} Or, if void main() {
// Compile-time error: `a` is non-nullable but no value was passed.
method();
// Compile-time error: `a` is non-nullable.
method(a: null);
// OK.
method(a: 5);
}
void method(
// Non-nullable (similar to what C# is doing to transition to NNBD)
a!,
b,
) {
// ...
} |
I was initially in favor of this syntax too. Unfortunately, it doesn't work well outside of function declarations. There are other places where you write a function type and need to be able to indicate which parameters are optional: // In a typedef:
typedef TakeOneOrTwo = void Function(int a, [int b]);
// In a type annotation:
void Function(int a, [int b]) takeOneOrTwo = ...; In those places, you can't specify a default value. The default value isn't part of the type, and putting a default value there wouldn't be meaningful. |
@munificent: If we had non-nullable types, could you write: // In a typedef:
typedef TakeOneOrTwo = void Function(int! a, [int b]);
// In a type annotation:
void Function(int! a, [int b]) takeOneOrTwo = ...; (Or NNBD): // In a typedef:
typedef TakeOneOrTwo = void Function(int a, [int? b]);
// In a type annotation:
void Function(int a, [int? b]) takeOneOrTwo = ...; I realize this is breaking (now you can't pass |
I was talking to Leaf about doing just this thing for named parameters. It might make sense for named parameters, but it breaks down for positional parameters. If changing a parameter's type to something nullable implicitly makes it optional, it means you can't change a non-trailing parameter type without messing with the arity and signature of the method in a likely breaking way. Also, it would cause weird things like making every positional parameter who's type is Object (which permits null) or dynamic implicitly be optional. I think that might be reasonable for named parameters where omitting one has no bearing on the others. But it's really weird for positional parameters where omitting one shifts the others forward. |
Or replace optional-positional parameters with overloads and fix that problem once and for all! |
Now you have a combinatorial number of problems. :) |
@munificent Do you know how other languages tackle this issue with typedefs? For example, Swift and Kotlin? |
I believe most other languages don't make optionality part of the type, just part of an invocation. A function type always has a single explicit signature with a fixed arity so there's no need to specify optional parameters in a typedef. Dart is a little special in that we almost have "first-class overloads". When you take a reference to a function that takes optional parameters, you get an object that you can call at runtime with multiple different signatures. |
Solution to #15.
As @munificent has pointed out before, in many mainstream languages it is common to make a parameter optional by giving it a default value.
Given that Dart is a language that strives to be familiar, I think that dart Dart should adopt this syntax as well. The current syntax is also unnecessary verbose, especially in the case of a required named parameter.
This is a breaking change, Dart gives a optional parameter with no default value implicitely the value
null
. With this syntax, you would have to be explicit about this:The text was updated successfully, but these errors were encountered: