dart-lang / language

Design of the Dart language
Other
2.65k stars 201 forks source link

Adding more null aware operators: ?+ , ?- , ?/ , ?* #2077

Open 0xba1 opened 2 years ago

0xba1 commented 2 years ago

Especially for integer and double arithmetic, it seems unnecessary to check if a value is null every time one needs to add or subtract. I propose we make more null aware operators that check if either value is null, and returns null if true but returns the result of the normal operation if false.

T? operator ?+(T? other) {
    if ((other == null) || (this == null) ) return null;

    return this! + other!;
}

Example
``` dart
int? int1 = null;
int? int2 = 5;
int? int3 = 3;
int int4 = 7;

int? int5 = int1 ?+ int2; // null
int? int6 = int2 ?+ int3; // 8
int? int7 = int3 ?+ int4; // 10
lrhn commented 2 years ago

There are grammar ambiguities with prefix operators (really just -), where {a?-b:c} can be either a map literal ({(a ?- b) : c}) or a set literal ({a ? (-b) : c}).

We can disambiguate by making ?- a single token, so it's always going to be the map literal above. That's a breaking change, but one which only affects unformatted code (formatted code will always have a space between ? and -).

With that, ?op where op is an infix operator can definitely mean null if either operand is null, and op if both are non-null.

It would mean that the static behavior of e1 ?+ e2 would be:

The runtime behavior would be:

Basically, it's short for (let v1 = e1 in v1 == null ? null : (let v2 = e2 in v2 == null ? null : v1 + v2)).

(I chose to short-circuit e2 evaluation here because ?. and ?[] both short-circuit what's after the ?, so it would be consistent to do it here too. It's not necessary.)

Could also work for x?++ and x ?+= 1.