Existential Operator / Null Propagation Operator

Dmitry Soshnikov dmitry.soshnikov at gmail.com
Tue Apr 7 01:35:00 UTC 2015

On Mon, Apr 6, 2015 at 11:33 AM, Christoph Pojer <christoph.pojer at gmail.com>

> Tim Yung and I have hacked on a reference implementation for the
> "Existential Operator" using esprima-fb and jstransform: "a?.b"
> Example:
> `a?.b` => `(a == null ? void 0 : a.b)`
> `a?.b.c` => `(a == null ? void 0 : a.b.c)`
> This must also make sure that `a` only gets evaluated a single time.
> Based on previous discussions on es-discuss and TC39, it seems that
> this was tabled for ES6. I think now is a good time to bring it up for
> ES7. There is precendence for this feature in other languages - it was
> recently added to C# and Hack and has always been in CoffeeScript.
> TypeScript is waiting for TC39:
> https://github.com/Microsoft/TypeScript/issues/16
> In the past, this topic has invited a lot of bikeshedding, but I'd
> like us to look past this. Several communities within and outside the
> JS community have identified the need for this operator. My
> understanding is that a decision needs to be made about whether the
> operator should short-circuit additional invocations in the call chain
> if the operand is null (aka. null propagation).
> For example, if `a` is null, should `a?.b.c`:
> 1) evaluate to `(void 0).c` and throw a TypeError?
> 2) short-circuit at `a` and return `void 0`?
> It appears that C# chose option #2 whereas Hack and CoffeeScript chose
> option #1. Our current implementation chose option #1

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:

`a?.b.c` and `(a?.b).c` have different semantics in case if `a` is `null`.

> but we'd be
> happy to build a reference implementation for option #2.
Yeah, (2) will make it compositional.

> I recall that another issue was that of transitivity. Right now,
> (a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be
> equivalent expressions. I think we need some input from the people on
> this list about whether this is okay or why we value transitivity for
> this operator.
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:

var v = a?.b?.c?.d

In other words, it's the same as:

var v = (((a?.b)?.c)?.d)

and in this case it becomes compositional (the semantics doesn't change
whether you apply grouping operator or not).

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.

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).

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.

[1] https://esdiscuss.org/topic/the-existential-operator#content-19

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150406/0f892e6b/attachment-0001.html>

More information about the es-discuss mailing list