language
language copied to clipboard
Request or suggestion for a!++ or a!+=x; syntax.
As in the title, ofcourse there are only rare cases it could be used. Some respected user from Discord Dart official channel suggested i might make a request. Here are some examples that i originally put on the discord channel:
c(int? a) {
// WATCH OUT: This is a very simplified function - i know a is not null
a! += 10; // error Missing selector such as '.identifier' or '[0]'.
a = a + 10; // overflow info: when the previous line exists this one doesn't show error;
}
d(int? a) {
a = a + 10; // error: The operator '+' can't be unconditionally invoked because the receiver can be 'null'. Try adding a null check to the target ('!').
}
// For comparison this, ofcourse, is fine - no a! += 10; way
e(int? a) {
a = a! + 10; // ofcourse fine.
}
Then the notable discord user suggested i could even do this:
void c(int? a) {
a!;
a += 10;
}
After the suggestion he wrote this: "I am not sure how useful this actually is in real-world scenarios since we should rarely need to do ! in our code, but should instead let Dart type promote our null-able variable so we can safely do those math operations.
But sure, there are cases where this could be needed (e.g. public nullable properties on objects)".
This one, and a?+= 2 too. That's really the more important one, because you can write a = a! + 1;, and it's not too bad, but for the ? variant you need to branch after the read, bind the value to a variable.
This comes back to wanting null aware operator invocations, like a ?+ 2, but Dart's syntax isn't happy about that for a number of reasons. (Ambiguity, {x?-y:z}, and extent, x?+y+z, mainly.)
For !, an a!=a+1 is also ambiguous, at the lexical level, and would have to have a space between ! and =.
A possible syntax could be x?.+ y, or x?.+(y) even. Then we'd allow x.+ in general, to refer to the operator+ method.
Then this would be a?.+=(2) and a!.+=(2). It would have to be special-cased, null-aware composite assignment behavior doesn't follow from being allowed to access the getter/setter in a nul-aware way.
Yeah, the additional dot syntax while probably not the best looking would make sense because some shorter syntax would be practical anyway and nothing better could be probably proposed (remembering the "ambiguity" or not-very-practical need to remember of a given space meaning especially for new dart programmers, f.e. "Oh, i will remove this space it is not nice."). But my opinion is average guy opinion. So i am watching this topic for how it develops.
But sure, there are cases where this could be needed (e.g. public nullable properties on objects)".
This is not justifiable. Nullable properties on objects should also be promoted, either by assigning it to a local or using if-case.
class C {
final int? property;
// ...
void case1() {
final property = this.property;
if (property != null) {
// Use promoted value
}
}
void case2() {
if (property case final property?) {
// Use promoted value
}
}
}
That said, I think what you are proposing should be possible. It's only intuitive, and I'm actually surprised it doesn't work (never needed it myself, so I didn't know this is invalid code).
@mateusfccp The "problem" with promoting to a local variable here is that we want to update the object property and not the local promoted variable.
Not a big problem. But that is why I told him that this was one of the cases where it might make sense.
Ah, that makes sense. We could still promote, like
class C {
int? property;
// ...
void case1() {
final property = this.property;
if (property != null) {
this.property = property + 1;
}
}
void case2() {
if (property case final property?) {
this.property = property + 1;
}
}
}
This would be the safest approach, and it is what I would do if I had this usecase, although I recon it's a little too verbose.
then we'd allow x.+ in general, to refer to the operator+ method.
Will that allow tearoffs like final add = 3.+; ?