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

Explainer: Add goal about semantic nonambiguity #6

Closed
js-choi opened this issue Mar 17, 2018 · 5 comments
Closed

Explainer: Add goal about semantic nonambiguity #6

js-choi opened this issue Mar 17, 2018 · 5 comments
Assignees
Labels
explainer/readme About readme.md

Comments

@js-choi
Copy link
Collaborator

js-choi commented Mar 17, 2018

An advantage that this proposal has is that parentheses can never change the meaning of a code without giving an early error. x |> (await #) is the same as x |> await #, and x |> (await y) and x |> await y are both early errors that require the developer to disambiguate between x |> (await y)(#) and x |> await y(#). This should be noted in Goals and in the Motivation, Core Proposal too, as well as the pipeline-operator wiki.

Edit: That advantage is moot. However, this proposal still has an advantage in that it forces the writer to make explicit which of these reasonable alternatives do they mean by x |> foo: x |> foo(#, y), x |> foo(y, #), and x |> foo(y)(#). This is also important, so I’m reusing this issue to track better explaining this in § Goals, in § Motivation, Core Proposal, and in the wiki. See #2 (comment).

@js-choi js-choi self-assigned this Mar 17, 2018
@js-choi js-choi changed the title Explainer: Add goal about parenthesis insignificance Explainer: Add goal about semantic ambiguity Mar 18, 2018
@js-choi
Copy link
Collaborator Author

js-choi commented Mar 18, 2018

This issue is moot, because Proposal 1 is stable with parentheses.
Cross-referencing from #2 (comment):

I hadn’t realized this until recently myself: (foo.bar)(x) retains its receiver for the same reason that delete (foo.bar) works. The grouping operator’s evaluation algorithm does not apply the GetValue abstract operation to its subexpression’s result, even if that result is a Reference. This means that it itself may evaluate to a Reference, and this allows function calls’ evaluation algorithm to use the Reference’s base.

I’m really glad that this fragility problem doesn’t seem apply to Proposal 1—though it does put a lot of the burden of its being useful on @rbuckton’s partial-application proposal, which smart pipelines would also subsume with a similar amount of syntactic complexity. Smart pipelines also try hard to prevent visual ambiguity, requiring x |> await o.p to be distinguished as x |> await o.p(y, #), x |> await o.p(#, y), x |> await o.p(y)(#), x |> (await o.p(y))(#), x |> (await o.p)(#) or x |> await #, all of which are reasonable interpretations.

Proposal Original/minimal proposal (F# only) Proposal 1 (F# only + await) Proposal 4 (smart pipelines)
x |> o.p o.p(x) o.p(x) o.p(x)
x |> (o.p) o.p(x) o.p(x) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> o.p or
x |> (o.p)(#).
x |> o.p(y) o.p(x)(y) o.p(x)(y) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> f(y, #),
x |> f(#, y), or
x |> f(y)(#).
x |> await Early Syntax Error: await not supported await x: await the value x Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await #.
x |> (await) (await)(x) – Syntax Error: Unexpected ) (await)(x) – Syntax Error: Unexpected ) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await #.
x |> await o.p Syntax Error: await not supported (await x) o.p – Syntax Error: Unexpected o.p Without Feature BA:
Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await o.p(#) or
x |> (await o.p)(#).
With Feature BA:
await o.p(x)
x |> (await o.p) Syntax Error: await not supported (await o.p)(x) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await o.p(#) or
x |> (await o.p)(#).
x |> await o.p(y) Syntax Error: await not supported (await o.p(y))(x) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await o.p(y, #),
x |> await o.p(#, y),
x |> await o.p(y)(#),
x |> (await o.p(y))(#),
x |> (await o.p)(#), or
x |> await #.
x |> new Syntax Error Syntax Error Syntax Error
x |> (new) (new)(x) – Syntax Error: Unexpected ) (new)(x) – Syntax Error: Unexpected ) (new)(x) – Syntax Error: Unexpected )
x |> new o.p TypeError: new o.p is not a function; it is an instance of o.p. TypeError: new o.p is not a function; it is an instance of o.p. Without Feature BC:
Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await o.p(#) or
x |> (await o.p)(#).
With Feature BC:
new o.p(x)
x |> (new o.p) TypeError: (new o.p) is not a function; it is an instance of o.p. TypeError: (new o.p) is not a function; it is an instance of o.p. Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> await o.p(#) or
x |> (await o.p)(#).
x |> new o.p(y) TypeError: (new o.p) is not a function; it is an instance of o.p. TypeError: (new o.p) is not a function; it is an instance of o.p. Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> new o.p(y, #),
x |> new o.p(#, y),
x |> new o.p(y)(#),
x |> (new o.p(y))(#),
x |> (new o.p)(#), or
x |> new #.
x |> () => y Syntax Error: Unexpected =>. Use
x |> (() => y) instead
Undecided Early Syntax Error: Unexpected =>. Use
x |> (() => y)(#) or
x |> (() => #).
x |> (() => y) (() => y)(x) (() => y)(x) Early Syntax Error: Topic-style pipeline needs topic reference #. Use
x |> (() => y)(#) or
x |> (() => #).

However, this proposal still has an advantage in that it forces the writer to make explicit which of these reasonable alternatives do they mean by x |> foo: x |> foo(#, y), x |> foo(y, #), and x |> foo(y)(#). This is also important, so I’m reusing this issue to track better explaining this in § Goals, in § Motivation, Core Proposal, and in the wiki. See #2 (comment).

@js-choi js-choi changed the title Explainer: Add goal about semantic ambiguity Explainer: Add goal about semantic nonambiguity Mar 18, 2018
@mAAdhaTTah
Copy link

In F#, x |> await o.p is a SyntaxError. It'll require parentheses to achieve the stated semantics.

@js-choi
Copy link
Collaborator Author

js-choi commented Mar 18, 2018

@mAAdhaTTah: Ah. Why is it an error? The syntax of x |> await o.p intuitively groups as x |> (await o.p), and await (o.p(x)) and (await o.p)(x) both seem like reasonable interpretations of that to me.

@mAAdhaTTah
Copy link

That ambiguity is part of the reason; x |> await is the whole expression, so o.p is a separate expression, and an expression next to an expression is a SyntaxError.

That's what I would like it to be, anyway. I'm drawing that interpretation from here: tc39/proposal-pipeline-operator#85

@js-choi
Copy link
Collaborator Author

js-choi commented Mar 18, 2018

Good to know; thanks! I will update the wiki table later today.

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

No branches or pull requests

2 participants