The Wayback Machine - https://web.archive.org/web/20191214130947/https://github.com/dart-lang/language/issues/110
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

Null Safety: Sound non-nullable types with incremental migration (NNBD) #110

Open
leafpetersen opened this issue Nov 28, 2018 · 38 comments
Open
Assignees
Labels

Comments

@leafpetersen
Copy link
Member

@leafpetersen leafpetersen commented Nov 28, 2018

This is a solution proposal for #71. The proposal will cover both the intended final language design, and the language, tooling, and ecosystem support required for the migration. A roadmap describing the general goals and desired properties of the feature is here. Discussion of specific details of the language design is underway.

All NNBD related issues:

Topic specific discussion issues for resolution:

@leafpetersen leafpetersen self-assigned this Nov 28, 2018
@mit-mit mit-mit added this to Being discussed in Language funnel Nov 29, 2018
@mit-mit mit-mit moved this from Being discussed to Being spec'ed in Language funnel Nov 30, 2018
@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Nov 30, 2018

I've added a draft of the roadmap for this proposal, linked from the header comment.

@yjbanov

This comment has been minimized.

Copy link

@yjbanov yjbanov commented Dec 8, 2018

@jmesserly I'm not sure how to constructively move the NNBD discussion from #125 here, because the my suggestion is all about linking the two issues. But I'll try:

I suggest that, as a first step, we introduce sound non-nullable types as part of immutable types (#125). This has several advantages:

  • It would be a non-breaking change: immutable types is a new feature so having them NNBD doesn't break any existing code.
  • It could have the biggest performance impact: if non-nullability is implemented such that many highly-used types can be inlined, such as double, int, bool, enum, String, we could significantly improve memory layout efficiency.
  • It would give us a chance to get the syntax and semantics right and educate users before rolling NNBD to the "normal" classes, which does require a bigger migration.
@jmesserly

This comment has been minimized.

Copy link

@jmesserly jmesserly commented Dec 8, 2018

IMO, linking the two proposals would be counterproductive. We are working hard on NNBD, there is a lot of design & planning work going on. There aren't any major open questions on syntax or desired semantics. Linking the two would prevent us from pushing forward on NNBD, because immutable types has a lot of open design questions, and we'd have to delay work on NNBD until that's resolved.

(Also it could be confusing if different parts of the language treat int as having different non-nullability. It would be really nice if int always means non-null, and int? always means mean nullable. The NNBD proposal achieves that.)

@yjbanov

This comment has been minimized.

Copy link

@yjbanov yjbanov commented Dec 8, 2018

That's fine too, it was just an idea. I don't have enough context to know how best to proceed, so if you believe that NNBD and immutables should proceed completely independently, then they should :)

@jmesserly

This comment has been minimized.

Copy link

@jmesserly jmesserly commented Dec 8, 2018

Makes sense :). Yeah, we seem to be gathering a lot of momentum behind Leaf's proposal. It's really exciting! I think we'll be able to apply the many lessons of Strong Mode to NNBD, to make the migration as easy & rewarding as possible. (e.g. ideally it's non-breaking for code that isn't migrated. Until you turn on NNBD, you don't break. Once you turn it on, you have to fix some errors, but you gain some degree of null safety, even if everything else isn't migrated yet. Once everything in an app is migrated, then it has sound null safety. It's pretty neat.)

dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 11, 2018
... which in this CL will always null.
This is the first step when adding NNDB support as outlined in
dart-lang/language#110

Change-Id: If3810bcaf1b73e70924f09d619e2a84e7d5ba8d6
Reviewed-on: https://dart-review.googlesource.com/c/86860
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 11, 2018
This adds code to ignore trailing `?` in `as` and `is` expressions
because the trailing `?` may be part of the larger expression.
At the moment, this change is a no-op, but will become active
when a subsequent CL lands support for nullable types as part of
dart-lang/language#110

Change-Id: I829d6aee0f11957ca9b5e143000005031649449f
Reviewed-on: https://dart-review.googlesource.com/c/86960
Reviewed-by: Brian Wilkerson <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 11, 2018
... as part of adding NNBD as outlined in
dart-lang/language#110

This only supports parsing simple nullable types
such as int? and List<int>? while subsequent CLs
will add support for parsing more complex types.

Change-Id: I3cc5c65d20bf3732a39cab0e823b2f7332342866
Reviewed-on: https://dart-review.googlesource.com/c/86961
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 12, 2018
... which in this CL will always null.
This is another step when adding NNDB support as outlined in
dart-lang/language#110

Change-Id: I3974fcb885c63be4af9d1007258383f3f8191ae0
Reviewed-on: https://dart-review.googlesource.com/c/87080
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 12, 2018
…tion type

This only supports nullable return values of the form

<identifier> '?' 'Function' '(' ...

This is an increment CL in the ongoing effort to add nullable type support
as outlined in dart-lang/language#110

Change-Id: I42febae9f88f7e4d8b05907988deab97c7a7425c
Reviewed-on: https://dart-review.googlesource.com/c/87081
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 13, 2018
This adds support for nullable types of the form

<identifier> '.' <identifier> '?'

and

<identifier> '.' <identifier> '?' 'Function' '(' ...

This is an increment CL in the ongoing effort to add nullable type support
as outlined in dart-lang/language#110

Change-Id: I526aecbe64bacbd442cea0b4c52d36ff23b0443b
Reviewed-on: https://dart-review.googlesource.com/c/87083
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 14, 2018
This reverts commit 7720689.

Reason for revert: Breaks parsing less common conditionals (e.g. b ? c = true : g();)

Original change's description:
> Add support for prefixed nullable type
> 
> This adds support for nullable types of the form
> 
> <identifier> '.' <identifier> '?'
> 
> and
> 
> <identifier> '.' <identifier> '?' 'Function' '(' ...
> 
> This is an increment CL in the ongoing effort to add nullable type support
> as outlined in dart-lang/language#110
> 
> Change-Id: I526aecbe64bacbd442cea0b4c52d36ff23b0443b
> Reviewed-on: https://dart-review.googlesource.com/c/87083
> Reviewed-by: Brian Wilkerson <[email protected]>
> Commit-Queue: Dan Rubel <[email protected]>

[email protected],[email protected]

Change-Id: Ib5e74b4aad239f561a33eae9d95dffa2693037f7
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/87282
Reviewed-by: Dan Rubel <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 14, 2018
…unction type

This reverts commit 11d081d

Reason for revert: Breaks parsing less common conditionals (e.g. b ? c = true : g();)

Original change's description:
> Add support for simple nullable type return value in generalized function type
>
> This only supports nullable return values of the form
>
> <identifier> '?' 'Function' '(' ...
>
> This is an increment CL in the ongoing effort to add nullable type support
> as outlined in dart-lang/language#110

Change-Id: I99bce29619d4e448193e3c81fa86a982791b1f77
Reviewed-on: https://dart-review.googlesource.com/c/87283
Reviewed-by: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 14, 2018
This reverts commit bc8c7cf

Reason for revert: Breaks parsing less common conditionals (e.g. b ? c = true : g();)

Original change's description:
> Add support for parsing simple nullable types
>
> ... as part of adding NNBD as outlined in
> dart-lang/language#110
>
> This only supports parsing simple nullable types
> such as int? and List<int>? while subsequent CLs
> will add support for parsing more complex types.

Change-Id: I49a21a85dca19241e3b23ed5c9fb6084e70f2000
Reviewed-on: https://dart-review.googlesource.com/c/87284
Reviewed-by: Dan Rubel <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Dec 17, 2018

I've updated the header with some sub-issues for discussing specific topics.

dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 18, 2018
... as part of adding NNBD as outlined in
dart-lang/language#110

This only supports parsing simple nullable types
such as int? and List<int>? while subsequent CLs
will add support for parsing more complex types.

Change-Id: I144858946cb115755af437299899c2631105bf8c
Reviewed-on: https://dart-review.googlesource.com/c/87501
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 18, 2018
This reverts commit c5fd11b.

Reason for revert: Conditional expression lookahead may modify the token stream

Original change's description:
> Add support for parsing simple nullable types
> 
> ... as part of adding NNBD as outlined in
> dart-lang/language#110
> 
> This only supports parsing simple nullable types
> such as int? and List<int>? while subsequent CLs
> will add support for parsing more complex types.
> 
> Change-Id: I144858946cb115755af437299899c2631105bf8c
> Reviewed-on: https://dart-review.googlesource.com/c/87501
> Reviewed-by: Brian Wilkerson <[email protected]>
> Commit-Queue: Dan Rubel <[email protected]>

[email protected],[email protected]

Change-Id: Ie1f47e7384ff51159aa2ebeb21561455b8e6287f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/87620
Reviewed-by: Dan Rubel <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 18, 2018
... as part of adding NNBD as outlined in
dart-lang/language#110

This CL updates the parser to recognize two specialized comments at the
beginning of a library of the form '//@NNBD' and '//@NNBD*' for use
by the analyzer to aid developers when converting their libraries
to be non-nullable by default.

In addition, the AstBuilder now populates the generated analyzer AST
with nullable type information.

Change-Id: I80d221dd138973aa32f05bde631245d9ac6ee10f
Reviewed-on: https://dart-review.googlesource.com/c/87540
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
dart-bot pushed a commit to dart-lang/sdk that referenced this issue Dec 21, 2018
... as part of adding NNBD as outlined in
dart-lang/language#110

This only supports parsing simple nullable types
such as int? and List<int>? while subsequent CLs
will add support for parsing more complex types.

Due to current parser limitations, it also only supports
nullable types in a limited number of statements such as

T? t;
if (x is String?) {}

In addition, address comments in
* https://dart-review.googlesource.com/c/sdk/+/87880
* https://dart-review.googlesource.com/c/sdk/+/87881

Change-Id: Ife4afadc0b72906fc0c4e9b1977ad838041c2a84
Reviewed-on: https://dart-review.googlesource.com/c/87920
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Dan Rubel <[email protected]>
@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Dec 22, 2018

Added links to two new discussion issues in the header comment.

@rrousselGit

This comment has been minimized.

Copy link

@rrousselGit rrousselGit commented Jun 17, 2019

Is there there any discussion around prototype overload for non nullable types caused by optional parameters?

There are a few objects that behaves differently based on whether an optional argument is present or not.

One example is StreamBuilder. If initialData is passed, then it's prototype is:

StreamBuilder<T>(
  initialData: T, 
  builder: (BuildContext, AsyncSnashot<T>) => Widget, 
)

But if omitted, the prototype is:

StreamBuilder<T>(
  initialData: null, 
  builder: (BuildContext, AsyncSnashot<T?>) => Widget, 
)

Similarly, there are a few asserts performed by widgets like Positioned (that accepts many parameters, but not all at once) which could be removed using a null safe prototype overload.

@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Jun 21, 2019

Is there there any discussion around prototype overload for non nullable types caused by optional parameters?

I'm not entirely sure what you mean, but I think the answer is no. This might be more of a question for the flutter framework to answer - how they plan to migrate their API here. We don't have overloading in Dart, and won't get it any time soon.

For this API, it looks to me like either you have to either:

  • split this into two different constructors
  • make initialData required, which would force T to be a nullable type if you want to pass null for it
  • make initialData have type T? and keep it optional. I think this requires AsyncSnapshot<T?>
@jodinathan

This comment has been minimized.

Copy link

@jodinathan jodinathan commented Jul 22, 2019

Indentation for NNBBD now works with WebStorm 2019.2.

@derolf

This comment has been minimized.

Copy link

@derolf derolf commented Aug 24, 2019

Is there there any discussion around prototype overload for non nullable types caused by optional parameters? ...

@leafpetersen I think the question is in general: what if you have two parameters where exactly one is null, but not the other.

Usually, you do assert((a == null) != (b == null)).

It would be nice to instead list all possible “variants” of the function signature and bind it to one implementation, like:

void func(int? a, int b),
void func(int a, int? b) {
...
}
@jodinathan

This comment has been minimized.

Copy link

@jodinathan jodinathan commented Aug 24, 2019

@Levi-Lesches

This comment has been minimized.

Copy link

@Levi-Lesches Levi-Lesches commented Aug 26, 2019

Hi, is there an ETA on non-nullables? Even a very loose one, like tomorrow, 5 months, or 2 years from now.

@rrousselGit

This comment has been minimized.

Copy link

@rrousselGit rrousselGit commented Aug 26, 2019

Hi, is there an ETA on non-nullables? Even a very loose one, like tomorrow, 5 months, or 2 years from now.

There's a flag for a preview usually. Here's the flag for static extensions: dart-lang/sdk#37893 (comment)

I don't know the flag for nnbd, but it's likely that if you use the 2.5-dev and try to use nnbd syntax, the compiler will tell you to turn on the flag.

@derolf

This comment has been minimized.

Copy link

@derolf derolf commented Aug 26, 2019

The flag is --enable-experiment=non-nullable. However, the main issue is that the SDK itself has not migrated yet. For example, trying to use Map[] currently returns a non-nullable value and your != null or ?? checks will be flagged.

@munificent

This comment has been minimized.

Copy link
Member

@munificent munificent commented Aug 26, 2019

However, the main issue is that the SDK itself has not migrated yet.

We're working on that. :)

@Levi-Lesches

This comment has been minimized.

Copy link

@Levi-Lesches Levi-Lesches commented Aug 26, 2019

If you use the 2.5-dev and try to use nnbd syntax, the compiler will tell you to turn on the flag.

Yes, thanks, I see that now.

We're working on that. :)

So does anyone have a (relative) idea of when this will be ready, or at least usable?

@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Aug 30, 2019

It would be nice to instead list all possible “variants” of the function signature and bind it to one implementation, like:

Yeah, it would be nice. Unfortunately, not at the top of our list of things to tackle right now, sorry!

@leafpetersen

This comment has been minimized.

Copy link
Member Author

@leafpetersen leafpetersen commented Aug 30, 2019

So does anyone have a (relative) idea of when this will be ready, or at least usable?

We really don't want to promise dates yet. Everybody is working full out on this and extension methods right now, it will be ready when it's ready! You can search for NNBD in the sdk issue tracker to get a sense of where things are, and I'll try to update now and then when notable milestones are passed.

@Levi-Lesches

This comment has been minimized.

Copy link

@Levi-Lesches Levi-Lesches commented Sep 1, 2019

Ok, thanks!

@derolf

This comment has been minimized.

Copy link

@derolf derolf commented Sep 1, 2019

Wow, extensions functions are coming as well? That’s really cool. What about let/apply/run-constructs from Kotlin?

@derolf

This comment has been minimized.

Copy link

@derolf derolf commented Sep 14, 2019

For early adopters, is it possible to already run code that utilises the extensions?

See https://stackoverflow.com/questions/57934341/error-this-requires-the-non-nullable-experiment-to-be-enabled

@munificent

This comment has been minimized.

Copy link
Member

@munificent munificent commented Sep 16, 2019

Wow, extensions functions are coming as well?

Yes, extensions let you define all kinds of members: methods, getters, setters, index operators, operators, etc.

For early adopters, is it possible to already run code that utilises the extensions?

Not yet. We're pretty far along but there's still implementation work left to do. Stay tuned. :)

@derolf

This comment has been minimized.

Copy link

@derolf derolf commented Sep 28, 2019

dart-lang/sdk#38623

Is ‘Null’ nullable and is ‘Null’ the same as ‘Never?’.

@lrhn

This comment has been minimized.

Copy link
Member

@lrhn lrhn commented Sep 28, 2019

Null is nullable. It's equivalent to Never? (they are mutual subtypes), but not necessarily the same ... for some definition of "same".

@ollydixon

This comment has been minimized.

Copy link

@ollydixon ollydixon commented Dec 3, 2019

Hey, we converted an entire project over the last 3 days to use optionals since without them there's so much possiblity for crashes. Seems we can't compile it to release. Any solutions for this? Some setting to bypass it?

@lrhn

This comment has been minimized.

Copy link
Member

@lrhn lrhn commented Dec 3, 2019

@ollydixon
No, not yet. This is still a feature in development. None of our production compilers support it yet (and even if they did, the feature would probably still have enough bugs that it should not be used in production).

@Levi-Lesches

This comment has been minimized.

Copy link

@Levi-Lesches Levi-Lesches commented Dec 3, 2019

Any timeline? Even if it's vague

@mit-mit mit-mit changed the title Sound non-nullable types with incremental migration (NNBD) Null Safety: Sound non-nullable types with incremental migration (NNBD) Dec 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Language funnel
Being implemented
You can’t perform that action at this time.