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

Do we need a null assertion operator, and if so what is the syntax? #196

Closed
Tracked by #110
leafpetersen opened this issue Jan 29, 2019 · 8 comments
Closed
Tracked by #110
Labels
nnbd NNBD related issues

Comments

@leafpetersen
Copy link
Member

In some situations, program invariants may establish that a variable is non-null in a way that cannot be made apparent to the type system. Kotlin, Swift, and Typescript all have some form of null assertion operator to handle this.

The postfix ! operator has been proposed for this, since it is a familiar idiom from other languages (see below).

This issue is for discussion of the operator, and possible alternative syntax. cc @Hixie @munificent @lrhn @eernstg

For reference, the operator in other languages:

Kotlin has the !! operator, which throws if the argument is null

// Kotlin
var s : String? = null
s!!.length // Throws if null, then calls the method
s!! // Throws if null

Swift has both a ! (force unwrap) operator (throws if nil), and also an implicitly unwrapped type which causes an implicit unwrap on each use.

  // Swift
    var str : String?
    str = "Hello, playground"
    str!
    str!.count
    let strImplicit : String! = str
    strImplicit.count  // equivalent to strImplicit!.count

Typescript has a purely static null assertion operator.

var str : String | null;
str!
str!.length
@munificent
Copy link
Member

My preferences are:

  • Yes, we should have this operator.

  • It should be a postfix !, with the same precedence as ..

I don't think we need any special case support for !.. That should fall out naturally from using postfix ! followed by a method call. It also allows other important use cases:

int? n;
expectsInt(n!);

someJson["key"]!["subkey"];

var value = someMap["key"]!;

@leafpetersen
Copy link
Member Author

That should fall out naturally from using postfix ! followed by a method call.

I think to make this work out in general, we either need the ! type operator, or we need to track nullability outside of the type system. See discussion here.

@leafpetersen
Copy link
Member Author

I think we're converging on a clear yes with syntax of !. @lrhn @eernstg @munificent is there more discussion to be done on this or should we mark this as decided?

@eernstg
Copy link
Member

eernstg commented Mar 11, 2019

+1 on !, and marking this as decided! ;-)

Syntactically, I think we will need a special case for !. as a member access; if we just make ! a postfix operator then we won't be able to write things like e!.m(), just like we can't write e++.m(). But I have no doubts that we can do that.

@lrhn
Copy link
Member

lrhn commented Mar 11, 2019

Agree on !. We'll fiddle with the grammar to give it the most useful precedence.

@munificent
Copy link
Member

+1!

@leafpetersen
Copy link
Member Author

Syntactically, I think we will need a special case for !. as a member access;

We can't deal with this via precedence? In any case, however we handle it, we'll probably need to be sure we can handle e!..m, e!(a), e!<T>(a) as well.

@leafpetersen
Copy link
Member Author

There will be an operator, and the syntax is !.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
nnbd NNBD related issues
Projects
None yet
Development

No branches or pull requests

4 participants