Closed madskonradsen closed 5 years ago
@levithomason
IMHO, there should some criteria for reaching a conclusion to this convo. Ideas?
The proposed conclusion of the main author of the proposal (myself) is #34, dated from few days ago. At this point, I’m waiting for eventual comments or objections before possibly proceeding.
Very cool. I agree entirely and I've left my support there. I will bow out of this issue now assuming #34 is the answer.
I suppose I could get used to something like ?!./?![]/?!(), which vaguely parallels TypeScript's non-null assertion (expression!).
I like this idea, but unfortunately ?![]
/ ?!()
still conflict with ? :
operator. Change the order (!?
) may be ok.
But why not just use !.
/ ![]
/ !()
? It's short and easy to remember and nullish-coalescing can still use ??
, and to be honest it's more consistent with ??
and avoid confusion like coffee.
The only problem is it break TS compatibility, but this is not the most important operator in TS, and TS can easily change to !!.
/ !![]
/ !!()
.
@claudepache
The goal of
??
is precisely to be able to writea??[b]
anda??(b)
.
I like levithomason's proposal, a function call is really distinct from a property accessor, they shouldn't have the same form
Also why not a.?b
(the dot before)?
@caub .?
is possible, but what about x[y]
? I remember there was x[?y]
option in es-discuss, but looks too weird.
What about just .
?:
a..b
a.[b]
a.(b)
To me it looks prominent, and is quick to type and remember.
If you see an obvious case where it's not backwards compatible, I'm curious to know what that is
@TheNavigateur it doesn't convey much the meaning of 'optional', and also confusing with 2..toString()
number literal
@caub
and also confusing with 2..toString() number literal
2..toString()
is not an issue, because the proposed (2)..toString()
is observably equivalent to (2.).toString()
(number literals are never null).
or just (2).toString()
, I just meant visually confusing
@claudepache Even if it's not an issue formally, this still seems a bit confusing for developer intuition. I like how the current proposal includes ?
, which creates parallelism with the ??
proposal and this feature in other languages.
If ? must be in the operator then how about ?>
?
a?>.b
a?>[b]
a?>(b)
@TheNavigateur Actually, I like that one!
Looks pretty similar to pipeline tho.
There's another thread that talks about the syntax a bit more: #34
In an informal poll, ??.
seemed to be popular: https://github.com/tc39/proposal-optional-chaining/issues/34#issuecomment-333413308
In any case, should this issue be folded into that one?
I think >
conveys "propagate in this direction" (like an arrow) and I think the shape of ?>
is distinctive enough from the |>
(function call pipeline) and +>
(function composition) operators as to be immediately distinguishable from them. All the other proposals overlap with other operators in at least some way. I just think this one probably offers the least friction and best clarity.
Here's a proposal which resolves the cases that were considered problematic. It requires to surround the expression with parentheses if you want to use the bracket notation, that's it.
// a == null ? undefined : a.b
a?.b;
// (a == null ? undefined : a[d]) + c
(a?[d]) + c
// throws (missing the : part of the ternary)
a ? [d] + c;
// just a backward compatible ternary
a ? [d]+c : d;
// throws (missing the ? part of the ternary)
(a?[d])+c : d;
// throws
e ? a?[d]+c : d;
// OK
e ? (a?[d])+c : d;
// OK
e ? a ? [d]+c : d : f;
e ? (a ? [d]+c : d) : f;
The real beauty in that proposal is that you will have an early error in previous ES implementation because the closing parenthesis is not found before the ?
or at the end of the ternary.
That’s an unacceptable ergonomic cost - bracket access needs to be as seamless as dot access.
I'm not sure if I agree with @ljharb on this stance on ergonomics in general, but I don't see how adding parentheses addresses the grammar issue. You'd still have to read ahead to the closing paren to figure out whether this is ternary or optional chaining, wouldn't you?
Not sure if it’s too hard to do a lookahead. But if we would have to do a lookahead then there is no need to use parens until ternary expression involved. Then I find it reasonable to use parens to disambiguate the ternary part from the optional chaining.
One of the concerns here, which ruled out ?[
normally, was allowing streaming parsers. Currently, in principle, JavaScript can be parsed by something which just works left to right, without multiple passes or backtracking. If you allow ?[
for optional chaining, you have to read ahead further in the expression to figure out what token you're talking about. It doesn't really help whether you force parens around it--parens are easy to match, but if you were willing to look ahead for a matching paren, you'd be able to look to the end of the statement too. The issue is looking ahead an arbitrary distance like that.
Though ?>
idea seems ok for current JS, I worry about it being conflict with the usage of <>
in generic type (TypeScript/Flow) or JSX.
Might only be as much conflict as =>
I'm not sure (a?[b])
would require a lookahead (just an extra bit of state in eg; parseConditional or equivalent and a node rewrite, as we do for eg object patterns). Most JS parsers currently require a lookahead anyway.
But I certainly agree with @ljharb that requiring parens would be unacceptable.
Perhaps discussion about ?>
should move to #34.
that requiring parens would be unacceptable
Wouldn't be the first time. cf https://github.com/tc39/proposal-optional-chaining/issues/5#issuecomment-321973312
@Mouvedia that should have been unacceptable, and could have been avoided. That's not a precedent to knowingly add another huge footgun along with new syntax.
There's some kind of poll on #51.
Why not think about it as a "?." operator with its own, slightly different, semantics, rather than spending a few years coming up a with a pristine proposal that won't satisfy all anyway?
Why don't we just close this issue and stick to the current proposal?
It's easy to read (less visual clutter than ??
), unambiguous and doesn't collide with the null coalescing operator nor with common sense – |
is binary OR (or type union in TypeScript), :
always separates name from value (or from type in TypeScript). Your new proposals don't seem lead anywhere nor do they solve any problem and .(
is a thing I guarantee you'll get used to.
I'm very very glad to see this become resurrected. One thing I'm curious about is why you chose to have a dot after the question mark in case of function invocation and why you have a dot between question marks and square bracket notation. It seems strange to me, but perhaps i'm too biased by having written too much CoffeeScript.