-
Notifications
You must be signed in to change notification settings - Fork 75
Possibly an even cleaner syntax #29
Comments
Definitely do not agree with this idea. This is magic and implicit. If I want some of the member accesses in the chain to be required, then the current proposal allows it - whereas yours would force me to separate my chain into multiples. |
Yes, I agree that the implicit nature of this proposal bugs me too. Thanks for your feedback! |
An explicit alternative might be an additional syntax sugar, something like: // applies optional chaining to all subsequent property lookups
const name = ?user.settings.account.lastname
// an equivalent of
const name = user?.settings?.account?.lastname |
I think this hints on a real world vs theory thing for me, I think the majority of use cases for optional chaining will be defensive programming, where 95% of the time developers are wanting to deeply access a property as in the example above. Saying it's magic might be a hint that the implementation may not be possible but I think it's important with new syntax to be open minded. |
The proposed chain assumes a common expectation about the entire access chain. It's entirely possible that we might want While the current syntax might be slightly verbose for deep access chains, it's possible to express heterogeneous expectations about that chain. |
I don't think the concept disagrees or disallows that scenario, it's more about favouring less verbosity for the common case. FWIW, I'm playing devils advocate as I think decisions should be driven by data, not emotion - a feeling might suggest there's a problem, but should be backed up with some analysis. For an argument that was well written up I think it deserves that. |
While it technically doesn't prevent the expression of heterogeneous expectations, it becomes far more verbose:
By making assumptions about the entire access chain, the proposal greatly reduces the operator's flexibility in order to save just 2 characters in the example. That's a poor tradeoff. |
|
After reading through the feedback, I agree with @tvald's comment that having But @meandmycode makes a good point that many of the use cases would be for defensive programming, and thus having something that caters for the (arguably) main use case would be good. I'd bet that once this proposal is accepted, this shorthand would be one of the first thing many people would be asking for. So in that light, what do you think about @darsain's idea of having an operator that does allow for that:
|
It would be great but that would require to support the parentheses version as well:
|
Optional chaining and nullary coalescing are already syntactic sugar. I would propose no sugar be added to the sugar. Too much sugar. |
@levithomason imho, the whole point of these things is to make code more concise and comfortable to write, and this: ?user.settings.account.lastname Is the 99% use case we should be focusing on. Just imagine how annoying it is going to be typing the question mark before each dot: user?.settings?.account?.lastname |
I just prefer explicit and a little more verbosity. I don't think it is a good thing to make things more concise for the sake of being concise. I subscribe to the code is for humans not machines idea, and I believe it applies to syntax as well. It is the same reason I've come to reject almost all forms of abbreviation in code. We have minifiers for making things concise, outside of that let's make it human readable and explicit. Just my 0.02. |
Annoying, or clear and explicit? |
Someone will write a babel-plugin for it anyway ;) |
Completely wrong. According to statistics gathered from CoffeeScript usage in #17:
564/4627 is about 12%, not >90%. |
@claudepache is right. My initial thoughts was that the repositories used by coffeescript-soak-stats are mostly libraries and simple applications. Maybe usage by more complex applications (with more complicated data structures) would be different. But this is not the case. When I ran the same tests with the most popular CoffeeScript applications on GitHub (sorted by stars), as opposed to libraries and applications, the percentage that used "soak operations chained on top of another soak" was around 11%.
The following repositories were used:
Interesting to note that in the yakyak repository, usage was at 33%, whereas others are as low as 5.2%. It implies that for applications with heavily nested data structures, they will use consecutive optional chaining frequently, and would benefit heavily with the I still think 11 - 12% isn't a large percentage, but it's still significant enough. |
Great to see some real data 👍 the stats seem to disagree that this would be the common case, but I'm not sure they accurately say that developers would rather be explicit. The stat only counts chained use, but it's not considered against if the developer even has the opportunity (i.e., it would be better to see counts for deep property access |
But, as language designer, I want to force them to be explicit (unless strong reason against that), for their own good and for the sake of those that will read their code... The current Optional Chaining proposal is carefully designed, so that the developer has the opportunity to express exactly what they mean, not less and (importantly) not more. That is, when I write: a.b?.c.d(x).e I express that that As shown by the stats, cases where there are at least two property accesses in the chain and you want optional chaining at each level, is not the general case, not even the majority case.
Agreed. Healthy diet also includes salt. |
Whilst I'm personally not sure this additional syntax is needed (an implied syntax version), I'm not sure it's as simple as this is bad language design because its not explicit, look at statically typed languages for example that have evolved to imply types in various places, I think a more accurate argument might be that it feels unusual for current ecmascript and it's value add over the explicit syntax is too minor. But consider operators like |
@meandmycode |
Yes certainly not the context I was suggesting. |
I'm following this thread for some time now, and I'm not convinced yet that this is a good idea. And the lack of consensus seems to confirm that |
What's wrong with one of the listed "workarounds"?
Seems explicit enough to me. |
Sure, the workaround is explicit, but it's the proposed default behavior that's being criticized. This line isn't explicit:
|
Well then I propose that the parentheses variant be the "default behavior". To be clear, that would be it, nothing else. |
The story so far...
I think the consensus here is that the original proposal to have What me and @meandmycode are still arguing for is the additional syntax of having The counter-argument (or part of it) is that statistically, there's not enough demand for that use to justify the additional sugar. My counter argument is that for some projects, the usage is still high enough that this additional syntax would be valuable. |
Ultimately I wanted to ensure we were open minded about syntax, to avoid a so-called baby duck syndrome - I think it's important to challenge your own gut-feeling (which I think it has* been). For what it adds I personally think the additional syntax is conceptually OK but statistically questionable if people would use it and it does feel like something that could only be reasoned about properly after optioning chaining in its current form is the norm in the ecosystem. |
TL;DR In short, I just don't think it is a good idea 😕 Just type a few question marks when needed.
Over the years I've found most readability issues, both mine and others', to be resolved with only a few weeks exposure. After that, we learn to read differently and it feels normal. In my experience, resistance or unwillingness to change is often labeled a readability issue for convenience. That said, I don't believe there is anything more readable about either one of these syntaxes given some time and syntax highlighting.
For me, this is hardly the main case. I do not think that because something is valuable that it also must be a good thing. I also don't believe that popularity is necessarily an indicator of a good thing either. I have many exceptions to the proposal that I haven't shared. Here are some of my main gripes:
|
@ all: Thanks for your input. I’ve added an entry in the FAQ explaining briefly why we won’t do that. If you think that this FAQ entry ought to be improved, do not hesitate to share your suggestion. |
I have an idea that incorporates parts of #9, that I wish to discuss here.
Proposed Amendments
Let's say we have this:
This will turn into the following with the Optional Chaining Operator:
This is a very common use case, and I'd argue the most common use case for the optional chaining operator. Would I be jumping the ship in saying it'll be cleaner to simply have this:
So that everything left of the
?.
would be evaluated 'step-by-step' and if any of the steps arenull
orundefined
, then the expression returnsundefined
The semantic of the operator would change from:
To:
In the of the current proposal, you have the example:
So what if
b[3]
evaluates toundefined
? Then it would throw an error. By having the?.
operator evaluates the entire chain, we can omit having many?.
operators.Why this might not be a good idea
user.settings
object always exists, then this new proposal would be performing 2 superfluous checks?
after the penultimate operand, which can seem unnaturalWorkarounds
Grouping - If we can be sure that
user.settings
exists, then we can groupuser.settings.account
together so the?.
operator will treat that group as one block. I.e.(user.settings.account)?.lastname
New syntax - maybe something like
user.settings.account.lastname ?| 'default'
, where?|
will essentially be the same asuser?.settings?.account?.lastname || 'default'
. The'default'
may be omitted to produce the same result as the current proposal -user.settings.account.lastname?|
would be the same asuser?.settings?.account?.lastname || undefined
, which is the same asuser?.settings?.account?.lastname
This will actually allow the operator to be much more powerful, as it can incorporate the Nullary Coalescing operator into the optional chaining operator.
My Thoughts
I feel like the current proposal is good enough, and allows you to be explicit rather than implicit, with the small downside of the code looking more verbose than it could be. I feel this change is unnecessary, as it is, but if it can be combined with the Nullary Coalescing operator, it could be a worthwhile discussion.
Tagging @tvald as he commented in a relevant prior discussion
Tagging @gisenberg as he is the author for the Nullary Coalescing operator proposal
Tagging @claudepache, @ljharb, @Mouvedia, @nerfpops, @adaptabi, @rattrayalex, @ittledan for their participation on #9.
The text was updated successfully, but these errors were encountered: