<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Apr 6, 2015 at 11:33 AM, Christoph Pojer <span dir="ltr"><<a href="mailto:christoph.pojer@gmail.com" target="_blank">christoph.pojer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Tim Yung and I have hacked on a reference implementation for the<br>
"Existential Operator" using esprima-fb and jstransform: "a?.b"<br>
<br>
Example:<br>
<br>
`a?.b` => `(a == null ? void 0 : a.b)`<br>
`a?.b.c` => `(a == null ? void 0 : a.b.c)`<br>
<br>
This must also make sure that `a` only gets evaluated a single time.<br>
<br>
Based on previous discussions on es-discuss and TC39, it seems that<br>
this was tabled for ES6. I think now is a good time to bring it up for<br>
ES7. There is precendence for this feature in other languages - it was<br>
recently added to C# and Hack and has always been in CoffeeScript.<br>
TypeScript is waiting for TC39:<br>
<a href="https://github.com/Microsoft/TypeScript/issues/16" target="_blank">https://github.com/Microsoft/TypeScript/issues/16</a><br>
<br>
In the past, this topic has invited a lot of bikeshedding, but I'd<br>
like us to look past this. Several communities within and outside the<br>
JS community have identified the need for this operator. My<br>
understanding is that a decision needs to be made about whether the<br>
operator should short-circuit additional invocations in the call chain<br>
if the operand is null (aka. null propagation).<br>
<br>
For example, if `a` is null, should `a?.b.c`:<br>
<br>
1) evaluate to `(void 0).c` and throw a TypeError?<br>
2) short-circuit at `a` and return `void 0`?<br>
<br>
It appears that C# chose option #2 whereas Hack and CoffeeScript chose<br>
option #1. Our current implementation chose option #1</blockquote><div><br></div><div>Hold on, I guess it's a typo, since as discussed in the internal conversation, and based on the implementation, your current prototype transform implements option (2). I.e. it's not yet compositional. CoffeeScript also has option (2), and is not compositional, since:</div><div><br></div><div>`a?.b.c` and `(a?.b).c` have different semantics in case if `a` is `null`.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> but we'd be<br>
happy to build a reference implementation for option #2.<br>
<br></blockquote><div><br></div><div>Yeah, (2) will make it compositional.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I recall that another issue was that of transitivity. Right now,<br>
(a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be<br>
equivalent expressions. I think we need some input from the people on<br>
this list about whether this is okay or why we value transitivity for<br>
this operator.<br>
<br></blockquote><div><br></div><div>Yeah, potentially we could agree it's being non-compositional. Otherwise, it will be full-chain "verbose" version. I.e. to get a null-safe `d` property, you should write `?` after each property access:</div><div><br></div><div>```</div><div>var v = a?.b?.c?.d</div><div>```</div><div><br></div><div>In other words, it's the same as:</div><div><br></div><div>```</div><div>var v = (((a?.b)?.c)?.d)</div><div>```</div><div><br></div><div>and in this case it becomes compositional (the semantics doesn't change whether you apply grouping operator or not).</div><div><br></div><div>But again, as was mentioned in [1], probably it's "too verbose", and hence may not hit standardization. I'd say it's fine -- it works in most of the case, and usually should not be that verbose. OTOH, we still may have a non-compositional (short-circuiting) version.</div><div><br></div><div>FWIW, in Hack programming language I also implemented the "verbose" version, hence it's compositional. The details of the implementation can be found in [2] (we've just recently added it to Hack).</div><div><br></div><div>On the topic whether it should be prefix or postfix: I'd personally prefer postfix, since it will be intuitive from other languages. However, if we won't be able to solve all grammar challenges, prefix version could be fined as well.</div><div><br></div><div>[1] <a href="https://esdiscuss.org/topic/the-existential-operator#content-19">https://esdiscuss.org/topic/the-existential-operator#content-19</a></div><div>[2] <a href="https://github.com/facebook/hhvm/commit/35819cdcf2c80edc22fb3e2e4a6a27f352fb9305">https://github.com/facebook/hhvm/commit/35819cdcf2c80edc22fb3e2e4a6a27f352fb9305</a></div><div> </div></div>Dmitry</div></div>