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

Created on 29 Jan 2019  路  8Comments  路  Source: dart-lang/language

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
nnbd

Most helpful comment

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

All 8 comments

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"]!;

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.

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?

+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.

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

+1!

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.

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

natebosch picture natebosch  路  4Comments

marcelgarus picture marcelgarus  路  3Comments

kevmoo picture kevmoo  路  3Comments

stategen picture stategen  路  4Comments

ShivamArora picture ShivamArora  路  3Comments