Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Spec short-circuiting semantics without using a transient Nil value #20

Closed
claudepache opened this issue Jul 25, 2017 · 6 comments
Closed

Comments

@claudepache
Copy link
Collaborator

@littledan #10 (comment)

For me, I feel more comfortable with the short-circuiting concept if it can be explained syntactically, as C# does, rather than by the propagation of a Nil value.

Your wish is our command! :-) Here is a first draft:
https://github.com/tc39/proposal-optional-chaining/blob/master/ShortCircuitingWithoutNil.md

Question to specialists (cc @waldemarhorwat): Is the grammar correct?

@littledan
Copy link
Member

I'm a huge fan of this new proposal. These are the syntax semantics I would've expected for ?. with short-circuiting. I am also happy with how the forms chosen match the CoffeeScript data (even though they are different forms than I would've abstractly guessed).

Any other thoughts? Maybe someone thinks it is too restrictive.

@ljharb
Copy link
Member

ljharb commented Jul 26, 2017

To clarify, this means a?.b.c.d() and a?.b.c do not throw when a is nullish, but (a?.b.c.d)() and (a?.b).c would?

@littledan
Copy link
Member

@ljharb I think so.

@claudepache
Copy link
Collaborator Author

@ljharb Yes.

The parenthesised forms will lead to different parse tree than the non-parenthesised ones (contrarily to the non-optional equivalent). Using spaces to denote precedence, a?.b.c is parsed as:

a    ?. b . c

while (a?.b).c is parsed as:

a ?. b   .   c

@alangpierce
Copy link

This alleviates most of my earlier concerns, so thanks.

It sounds like this structure will need to be reflected in any AST format, right? I think it would need to, since (a?.b).c and a?.b.c evaluate differently and thus should parse to different ASTs.

Following the format from http://esprima.readthedocs.io/en/latest/syntax-tree-format.html, seems like the new AST structure would be something like this:

interface OptionalChainingExpression {
    type: 'OptionalChainingExpression';
    expression: Expression;
    accessChain: ChainedAccessElement[];
}

type ChainedAccessElement = ChainedMemberAccess | ChainedCall;

interface ChainedMemberAccess {
    type: 'ChainedMemberAccess';
    computed: boolean;
    property: Expression;
}

interface ChainedCall {
    type: 'ChainedCall';
    arguments: ArgumentListElement[];
}

Does that look right? It also means that a?.b.c.d and a.b.c.d have significantly different parse trees, but maybe that isn't actually a big deal (and I see you tried to make it consistent and ran into trouble).

(I realize the focus here is on the spec grammar, which doesn't necessarily need to match AST formats, just curious what the implications are for tools authors.)

@claudepache
Copy link
Collaborator Author

The new spec is available at https://tc39.github.io/proposal-optional-chaining/

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants