Skip to content

[nnbd] Late Keyword is Redundant for Local Non-nullable variables without Intializers #1101

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

Open
creativecreatorormaybenot opened this issue Jul 17, 2020 · 4 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@creativecreatorormaybenot
Copy link
Contributor

creativecreatorormaybenot commented Jul 17, 2020

Late assignment of non-nullable local variables

void main() {
  int i;
  we();
  i = 42;
}

The above is strictly equivalent to the following:

void main() {
  late int i;
  we();
  i = 42;
}

This is because non-nullable variables also need to be assigned before first access. For nullable variables, the above does not apply because they can be accessed without explicit initialization.

Late lazy

Obviously, the late modifier is still useful for non-nullable local variables when they have initializers.

void main() {
  late int i = calculate();
  // w/e
  i;
}

This would be an argument for separating the keyword into two distinct modifiers (which is already the case under the hood as the two effects of the modifier are mutually exclusive).


Proposal

I think that any one of these actions is sensible given the above:

  • Do not allow late for non-nullable variables without initializers.
  • Separate the late modifier into two keywords, i.e. late lazy and late assign.
  • Make a lint for this being redundant.

Why?

To me the two effects, or better two kinds, of the late modifier make perfect sense, however, I think that interactions like this will make late very confusing for people who spend less time with Dart.

Related

#1100

@creativecreatorormaybenot creativecreatorormaybenot added the feature Proposed language feature that solves one or more problems label Jul 17, 2020
@eernstg
Copy link
Member

eernstg commented Jul 17, 2020

That is not quite true: A late local variable maintains the initialization discipline dynamically. This means that you can write more complex code that will initialize it, and the flow analysis won't try to prove that it is safe.

With a non-late variable it is an error to read it unless it is guaranteed to be initialized on all control-flow paths. For example:

void main() {
  bool b = true;
  late int i;
  if (b) i = 1;
  i; // OK with `late`, but compile-time error if `i` is not late.
}

Of course, if we change that to bool b = false; and keep late then it is a run-time error.

The notion of late lazy is actually expressed by having an initializer, and the fact that the = and the initializing expression are very visible should make it unnecessary to have the extra keyword lazy in front. The notion of late assign would presumably refer to the semantics when the initializer is absent. So I think you already have the semantics that you are asking for, it's just spelled a bit differently.

@creativecreatorormaybenot
Copy link
Contributor Author

@eernstg Yes, I said that it is very clear to me - just probably not very obvious for everyone 🙂

I see that there are edge cases, but a lint still makes sense because it can figure out when late is redundant.

@eernstg
Copy link
Member

eernstg commented Jul 17, 2020

Oh, but everything is obvious to everyone, of course, at least if we look again and squint a bit. 😄

And I agree that it could be quite helpful to have a lint which flags local variables that are late, but can be non-late.

@leafpetersen
Copy link
Member

We debated extensively whether to use different keywords for late vs lazy or just one. You can see some of the discussion here. In the end we decided to go with one, for better or for worse.

The subject of lint for unnecessary late was just raised here as well . cc @bwilkerson

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

3 participants