Skip to content
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

Rethink required to be optional for non-nullable named parameters without default values #3206

Open
Cat-sushi opened this issue Jul 7, 2023 · 2 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@Cat-sushi
Copy link

Cat-sushi commented Jul 7, 2023

There already have been several discussions such as #156, #878, #2050, and so on.
But, I think it is good time to rethink required to be optional.

Supporse,

class const C({/* final */ required int i});

final can be inferred by the compiler, because otherwise it is an error.
On the other hand, required is required!
I feel it weird.
Especially in context of primary constructors, terse syntax is justice.
Specify primary constructors by eernstg · Pull Request #3023 · dart-lang/language

In addition, under migration to null-safe code, {int i} had to be decided/ marked whether nullable {int? i} or required {required int i} by users.
Now, Dart 3 is fully null-safe and the migration tool has gone.

@Cat-sushi Cat-sushi added the feature Proposed language feature that solves one or more problems label Jul 7, 2023
@lrhn
Copy link
Member

lrhn commented Jul 8, 2023

If the request is to be able to omit required in primary constructors only, then we can discuss it.

For all other methods and constructors, the arguments from the existing issues still apply.

Omitting a required from a primary constructor would then be allowed if, well, not being required would be a compile-time error.

That would be a named parameter with no default value that:

  • Declares a non-late field which is final or potentially non-nullable.
  • Is an initializing formal for a non-late field which is final or potentially non-nullable.
  • A super-parameter for a required super-constructor parameter.

The problem with being implicit is that it allows errors to propagate.

If you intended a parameter to be required, but its type ended up being nullable, the parameter is now optional.
Someone starts using the constructor and omits the parameter.
It's now a breaking change to add required to the parameter.

Or you intend a parameter to be optional, but accidentally erased its default value, and it's now required.
You never intended that, but you get no warning because the parameter is just silently made required.
All your tests happen to pass the parameter, because your test goes through a helper method like:

void testFoo(String name, Foo expectedResult, int arg1, {String arg2 = theDefaultValue}) {
  test(name, () {
    expect(Foo(arge, arg2: arg2), equals(expectedResult));  // arg2 always passed!
  }
}

so you never actually test that the default value is there.

Safety sometimes require redundancy.

Allowing you to omit required in every primary constructor is probably too much.
Allowing it only for extension type, here there must always be precisely one required parameter, may be more reasonable. (If we allow named parameters in their primary constructors at all.)

I'm not sold.

(I'd much rather just make every parameter required if it has no default value. Then you must add = null to make nullable parameters optional, but we can remove both [...] and required syntaxes then. Bigger change, but if we are changing things, might as well do it properly!)

@Cat-sushi
Copy link
Author

Cat-sushi commented Jul 8, 2023

I knew default values are not parts of function signatures.
But, removal/ change of default values is almost always breaking, even with nullable parameters, regardless of required.
And, it's a responsibility of the function designer, but not of compiler.
So, I don't worry about accidental removal of default values very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

2 participants