Closed RyanCavanaugh closed 4 years ago
@schungx Fair enough, but it would help for the weird possibilities like this : a?['b']
or this a?()
.
+1 ?
a?['b']
and a?()
behave nicely in coffeescript, and they look good to me.
But then again, I might just be coffeescript-blind.
+1 Ruby just implemented the existential operator https://twitter.com/mikepack_/status/657229703443451904. Typescript needs this too, regardless of the specific syntax.
This would be make code cleaner π
+1 Need this!
Please, implenent ?. operator, as C# does
+1 I've been missing this for a long time
+1 so ugly to write: someVariable && someVariable.someMember when you could write: someVariable?.someMember
+1, this would be great.... (most wanted feature for me)
+1, it's a good idea! Only, if the object is complicated, the expression will be full of ?. after each property (var result=myValue?.a?.b?.c?.d?.e;) when I need to recieve a value of the last one (var result=?myValue.a.b.c.d.e;).
+1 - This is arguably one of the greatest features of CoffeeScript and is by far my team's most desired TypeScript feature after converting much of our code from CS to TS.
+1 however, this is too complex:
var x = { y: { z: null, q: undefined } };
var z: x|y|z = x?.y?.z;
I like this:
var x = { y: { z: null, q: undefined } };
var z: z|void = x?.y?.z;
x?.y?.z
's type is always the type of the z
field. Of course the type must be nullable and the actual value may be null. If it is non-null, then it must be of the type of the z
field.
+1 This would go well with Typescript's vision of easing development of large scale complex JS Projects.
Any updates on this? Is this a case of the community voting for this feature for it to be considered? Or has it been considered but there are some engineering challenges?
No updates so far because introducing new expression-level syntax is dangerous without some sort of proposal from the ECMAScript committee.
See https://github.com/Microsoft/TypeScript/issues/16#issuecomment-57645069.
Here is a more current discussion on existential operators (lots of thoughts, but doesn't look like a lot of action):
where should I write "+1" to help bring it to ES?
Closing this for now. Since there's not really anything TypeScript-specific that would require this at expression level, this kind of big operator change should happen at the ES spec committee rather than here.
The general tripwires for re-evaluating this would be a concrete ES proposal reaching the next stage, or a general consensus from the ES committee that this feature wouldn't happen for a long time (so that we could define our own semantics and be reasonably sure that they would "win").
life sucks
Deleting standalone :+1:s. Please use the GitHub reactions feature or send flowers and candy to your nearest TC39 representative.
Once I got used to it in coffeescript and Swift, there's no going back. TS is dead to me as it currently stands.
@algesten I can agree about swift
if we consider the language itself, not sure about long term coffescript
support (I use CoffeScript in production projects). We may agree to be sure of language analytics trends as for June 2016 like this where we can clearly see what's going on to coffescript
recently, while TypeScript
has seen the fastest growth in the past years:
TypeScript: Outside of Go or Swift, the fastest growing language weβve observed in recent years is TypeScript. The Microsoft-backed JavaScript superset and Angular 2 foundation has made significant gains for the second consecutive quarter, jumping from #31 to #26. That was the biggest single change in any Top 30 language, and the second largest jump overall (Standard ML, 7 spots). At #26, in fact, TypeScript is now tied with Erlang, one spot behind Powershell and four behind CoffeeScript, which is just outside the Top 20. The question facing the language isnβt whether it can grow, but whether it has the momentum to crack the Top 20 in the next two to three quarters, leapfrogging the likes of CoffeeScript and Lua in the process.
Until 2014 the coffescript
trends was more than positive as you can look here, that is when the decline started.
With the new typescript 2.0 strict null (undefined) checking, it is a must, because otherwise you cannot use function chaining!
This should be in the next version of ECMAScript. Considering this would be even more useful in vanilla JavaScript than TypeScript and considering that the implementation would naturally be a check for undefined or null as opposed to a truthy check, it should be trivial for TC39 to add.
The simple implementation and one which would be idiomatic in JavaScript, would simply be to short circuit when encountering either null or undefined, and return undefined.
@bterlson does this make sense? What are the odds of such a proposal being accepted?
One of the great benefits of typescript is "the future is given to you today". This is one of the features that I was surprised that are not already there.
I hope that it will be added soon as function chaining is popular idiom and will strict null checking it is no longer work unless the ?. operator is added.
TS 2 wonderful null checking made it from a nice to have to must have!
Reading through this thread I'm kind of surprised how this doesn't get more attention from the maintainers.
In an ideal world TypeScript should lead the way for ES and not reversely. Seriously, where would be TypeScript now if the TS team would always have waited for ESx to propose and finalize a feature or a syntax?
This syntax is really a "must have", as others have pointed it out. It even received some good proposals in this thread so far. I think the implementation should match these expectations.
a?.b
should be valid at compile-time if and only if a.b
is valid.null
or undefined
value then that value should be the return value.What do you think the parts are which can lead to disagreements when ES will specify it?
For a?.b
I do not see any conflicts with existing (and future?) syntax. If the parser finds the token ?.
it can treat it as 'safe navigation operator' (with expectations as described by @cervengoc).
Syntax conflicts arise only when allowing a?(b)
and a?[b]
, since these could also be interpreted as the start of a ternary ?:
operator expression. But for starters I think these could be put aside and supporting just the a?.b
syntax would already make a lot of developers happy!
In an ideal world TypeScript should lead the way for ES and not reversely.
In terms of expression-level syntax, we absolutely disagree. There's a committee driving a standard for a reason -- not so that one-off actions by one player can unilaterally decide the future of JavaScript.
This syntax is really a "must have", as others have pointed it out.
If this is a must-have for TypeScript, it's a must-have for JavaScript as well! Again, take your concerns to the ECMAScript committee.
What do you think the parts are which can lead to disagreements when ES will specify it?
At a minimum, I think there will be disagreement about whether the syntax short-circuits to null
or undefined
when encountering those values, or always short-circuits to undefined
. There is also going to be some contention around whether or not some form of bracketed syntax is supported. There's also the question of what the behavior of a?.b.c
is. There's also the question of ?.
vs .?
vs a.b?
. There's the question of what the effect of this on the delete
operator is.
The ES DIscuss thread on this is over 100 comments long. There's no lack of ambiguity! It's easy to look at one example in isolation and think there can't be tons of corner cases. There are. That's probably why no one has championed this at TC39 yet and also why we're not rushing to add a feature that has lots of ambiguity around how it should behave.
I apologize, I didn't read through the mentioned thread, I will definitely have a look at it to see more.
We see this a bit differently. About the committee, in my honest opinion this is one of the biggest reasons why JavaScript will never be good. Just for an example, many of the most successful software what I've seen (like Total Commander or IrfanView) are successful because they are maintained and designed by ONE person, and not by a *committee". Of course this is not a completely correct example. But I'm almost sure, that if for example you alone would have designed the complete ES6, then the world would be a better place now.
Also, the ambiguities which you've mentioned are in 99% theoretical things and kind of irrelevant from the developer's side. Who would care about what it returns, null
or undefined
? Just pick one, and we will use it like that.
All in all, you and that committee are on a different side than most of us, and things from that side are usually more complex than they really are. And this can lead to some contra-productivity to say the least. Don't take it personally, but according to my experience in general, some people would be better come out of the conference room more often and have a look at some code.
Of course no offense, don't take anything personally, I have a huge respect to you and all the TS team, because you did revolutionize many developers' client-side development including myself, and thank you for all your work. We're just a bit disappointed about this specific one I guess.
One last thought. I've ran through the mentioned ES thread, and one thing is completely sure: they are overcomplicating it. They want to design something which is good for every scenario.
I personally would be completely satisfied and happy with a conditional member access operator. Don't need conditional invocation, conditional index signature, don't need to support every fancy scenario which is valid JS code. That's all. But instead, they will likely keep sitting there and discuss how to do everything at once, which is a great plan, but we will have nothing at the end of the day.
All in all, you and that committee are on a different side than most of us, and things from that side are usually more complex than they really are.
I don't think you are reflecting the true status of Ryan or TC39 accurately. Ryan, and the TypeScript team, have set out very clear design goals for TypeScript. One of the original and still very current goals is that TypeScript is a superset of JavaScript. Not the language people would like it to be (e.g. Dart, Haxe). When it come to syntax, the TypeScript team have learned the hard way the cost of pre-inventing it (e.g. modules). We are headed headlong into a challenge with private members of classes too, where the proposed ES syntax is totally incompatible with the syntax TypeScript uses. Why? Because what may look uncomplicated on the surface is impossible to achieve given the run-time challenges of a language.
TC39 has "saved" JavaScript in my opinion. ES4 was abandoned, not because it lacked good, innovative ideas, but because it would break the internet. TC39 got themselves into shape, they have shared and been totally open in their discussions and how they make decisions and delivered us ES2015, which is a lot like ES4, but didn't break the internet. It is amazing that we essentially have JavaScript run-times that run code from 10 years ago just fine, but support many significant improvements to the language. ES2016 was the lull before the storm. ES2017 has a "reasonable" amount of functionality and change and a clear governing process that heads the right direction.
So being on the "different side" of things clearly has worked, in my opinion. Which beats expediency of "must have" features.
@kitsonk I didn't mean "different side" negatively, and especially I didn't mean to degrade the work what was put into TypeScript or ES6. What's more, the best thing in TypeScript IMO is that it really had and has a clear design goal, and it's well protected against becoming a havoc like many other opensource stuff.
I just wanted to tell that this very feature is a clear example of where a group of genius people will end up overthinking and overcomplicating things, instead of just going the easy simple way, and accept some limitations like not supporting invocations or index signatures, etc. Someone in that forum even suggested using this syntax in assignments, which is kind of crazy. I still think that this phenomenon is contra-productive in this sense.
I understand that on your side it's a pain that for example private members became incompatible with the final ES6 concept. But on the other hand, we HAD it. Way before ES6. And that's the main point from our side. Roughly speaking, we don't care about how you manage to emit the appropriate code for it, we're just happily using it. Same with modules, and everything. We (or at least I) didn't see those pains what you're talking about it, we were always happy with private members or modules.
This particular feature is in CoffeScript as I read about it. Why do we, simple developers always have to make compromises when choosing a platform/library/plugin, etc.? I mean always. This is kind of annoying. Here we have a great language, which has great potential, which completely leaves every other participants behind (including ES!), and which has successfully revolutionized a huge part of client-side development, and when it comes to this "simple" feature (I mean the member access part at least), we hear that it won't be implemented until ES commits to this.
I wanted to give folks a quick heads up that this feature moved from stage 0 to stage 1 at today's TC39 meeting.
Relevant commit: https://github.com/tc39/proposals/commit/cb447642290a55398d483f5b55fb7f973273c75d Meeting agenda: https://github.com/tc39/agendas/blob/master/2017/01.md
wow! that's huge!
Also worth a link to https://github.com/claudepache/es-optional-chaining
Some "surprises" I see here (not saying I disagree, just things that we probably would have done differently if we had done this earlier):
null
is not produced from an a?.b
expression: when a
is null
this produces undefined
insteada?.b.c.d
will not throw if b
and c
properties are undefined
~ Ryan can't read(a?.b).c
will not throw if b
is undefined~ Ryan can't reada?.b.c().d
will return undefined
if the c
invocation returns null
~ Ryan can't readdelete
operator is supporteda?.[x]
is supportedfunc?.(...args)
is supported, even for non-method calls (!)I'd expect to see change in those areas between now and stage 2.
I think coffeescript got it right.
a?.b.c throws if b is undefined.
a?() and a?[0] are both good.
- Propagation in chained dots: a?.b.c.d will not throw if b and c properties are undefined
- Propagation in presence of parens: even (a?.b).c will not throw if b is undefined
- Propagation even occurs on method calls: a?.b.c().d will return undefined if the c invocation returns null
Those points don't seem accurate to me. From the proposal:
a?.b.c().d // undefined if a is null/undefined, a.b.c().d otherwise.
// NB: If a is not null/undefined, and a.b is nevertheless undefined,
// short-circuiting does *not* apply
Wow, I totally misread that. You're right. Updating
@algesten from original proposal:
a?.()
b?.[0]
sweet. the operator can sort of be though of as ?.
then.
There's some additional conversation happening over here: https://github.com/estree/estree/issues/146
A quote that could apply well: Β«Make simple things easy, and difficult things possibleΒ». Thus perhaps, support the most common cases well, while skip (at least initially) the complicated/rare cases, while they are still allowed to be "done manually" with longer (existing) syntax.
Just my two cents
let a = b?.c?.d?.e;
to:
let a;
try{
a = b.c.d.e;
}catch(e){
a = undefined;
}
@cedvdb totally different semantics -- exceptions thrown in getters should not cause coalescing
@RyanCavanaugh yeah.. I didn't think this through.
Is this on the radar for implementation now, or will the TS team wait for the ES proposal to move further along?
It is on our short list; we still have a few questions/concerns but you should see movement on this in the comming month.
Current Status
Open questions
document.all
get?C# and other languages have syntax sugar for accessing property chains where
null
(or in our case,undefined
) might be encountered at any point in the object hierarchy.Need proposal on what exactly we should codegen, keeping in mind side effects of accessors.
Edit by @DanielRosenwasser February 27, 2018: This proposal is also called the "null propagation" operator.