Closed SomeRanDev closed 2 years ago
I do think this would make for a good addition, also combined with null coalescing (PR #85). For the index and call variants, ?.[
(resp. ?.(
) might be easier to parse.
The detailed design fails to design how exactly this would be implemented.
Also, there's still the open problem that cond?.1:.2
is valid syntax already.
Yes, the detailed design should mention the AST changes at least. I guess the least intrusive change would be an optional flag nullSafe
on EField
, ECall
, and EArray
(false
by default)?
Also is the cond?.1:.2
really a problem? ?.
followed by a letter or underscore begins a null-safe field access, whereas ?.
followed by a number is the start of a ternary and a shorthand float literal.
Also is the cond?.1:.2 really a problem? ?. followed by a letter or underscore begins a null-safe field access, wherease ?. followed by a number is the start of a ternary and a shorthand float literal.
Perhaps, but this is still something that has to be addressed in the proposal.
Anyway, my tentative opinion here is that ?.
and ?[
are useful, but ?(
is a step too far. I'll elaborate a bit later if necessary.
but
?(
is a step too far.
I find it useful for optional callbacks.
(nullableDynamicArrayContainsString?[0]:String)
is valid Haxe syntax, given var String = [1];
and var nullableDynamicArrayContainsString = false;
.
Maybe instead of ?[
we can add get
/set
methods to Array
after, like in Map
, and use arr?.get(0)
for such cases?
@RblSb Then we'll suddenly have code style debates about which variant should be used for array access (like we already have for maps). :/
(nullableDynamicArrayContainsString?[0]:String)
is valid Haxe syntax, givenvar String = [1];
andvar nullableDynamicArrayContainsString = false;
.
Wow, in retrospect I'm very embarrassed I overlooked this. The same can also be applied to the safe function call. It now makes a lot more sense to me why JS uses jsFunction?.()
or jsArray?.[0]
. With Haxe having very similar syntax, I think it makes sense to shoot for that (assuming safe array-access/function call are even included)? I'll update the proposal.
Yes, the detailed design should mention the AST changes at least. I guess the least intrusive change would be an optional flag
nullSafe
onEField
,ECall
, andEArray
(false
by default)?
I'll go ahead and move it from "Impact on Existing Code" to the "Detailed Design" with a bit more specificity. Wasn't sure if optional flags were desired when it came to AST? Figured new but I have no experience with designing Haxe AST, so I can't say myself.EMaybeField
/EMaybeCall
/etc would be used, or an ESafeNav(e:Expr)
that wraps around EField
, ECall
, or EArray
,
Also, there's still the open problem that
cond?.1:.2
is valid syntax already.
Will acknowledge in proposal as well.
It is adding syntax for something which, as a whole, is like quicksands.
In the end it may encourage some people using null
over things like haxe.ds.Option
.
While I occasionnally like to use nullability I am in general not for creating those syntaxes.
Option
generally yields poorer performance (more work for the GC, slower access).Null
. One could define map
/ flatMap
/ or
in userland (as is common practice for Option
). This is no different, except that it's less noisy, and it is built right into the language core - as is null
itself.But that's what I dislike, it's like defining a Maybe monad implemented over null. Why the privilege?
Can we imagine they are available as well for something like haxe.ds.Option
?
It's an operator that will be given a default meaning, just like +
has a default meaning for numeric types. If you want safe navigation operators for Option
too, you can create OptionTools
and (probably macro
) methods to handle ?.
there. Whether you like that Null
is given "privilege" is irrelevant given how common it is in Haxe and even more so external libraries.
Ok I see.
For me the biggest benefit of a safe navigation operator would be to reduce the boilerplate when using @:nullSafety(StrictThreaded)
in conjunction with class/instance variables. So we can avoid having to use temporary variables to satisfy null checks.
In the following case:
class Test {
static var myArray:Null<Array<Int>>;
static function main() {
// without @:nullSafety
myArray.push(1);
// with @:nullSafety(Strict)
if(myArray != null) myArray.push(1);
// with @:nullSafety(StrictThreaded)
final myArrayRef = myArray;
if(myArrayRef != null) {
myArrayRef.push(1);
}
}
}
So classVariable?.member()
should be expanded to something like:
final classVariableTmp = classVariable;
if(classVariableTmp != null) {
classVariableTmp.member();
}
when @:nullSafety(StrictThreaded)
is enabled.
This proposal has been accepted, see https://haxe.org/blog/evolution-meeting-2021/ for details.
Add safe access operators for nullable values.
Rendered version