Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Receiver operator vs ? token #32

Closed
mmkal opened this issue Feb 6, 2019 · 7 comments
Closed

Receiver operator vs ? token #32

mmkal opened this issue Feb 6, 2019 · 7 comments

Comments

@mmkal
Copy link

mmkal commented Feb 6, 2019

Reading the proposal, there are two sections that make sense independently, but in combination seem to be limiting the usefulness of the feature:

  • Support for receiver placeholder says a receiver placeholder wouldn't be supported because it would require finding ? in any expression, rather than just in ArgumentList, and runs afoul of visual ambiguity with the optional chaining proposal.
  • Choosing a different token says a different token is unnecessary because ? may only be used on its own in an argument list.

If a different token was chosen (say, one that can't be a variable right now, like * or ~), it would
no longer cause visual or semantic ambiguity with optional chaining, null coalescing or even ternary operators. And it would mean that down the line, the operator could be combined with some of those features.

Choosing ? will likely permanently close the door on the possibility of supporting a receiver placeholder. There are also downsides like the visual confusingness of a semantically-valid and unambiguous expression like f?.g(?, a ?? b, c ? d : e). * would be marginally better (even if the expression is over-complex anyway) - f?.g(*, a ?? b, c ? d : e)

Choosing * or ~ doesn't have those downsides. And even supporting a receiver placeholder wouldn't be a requirement for when the proposal became a reality, it'd at least be possible further down the line, as well as more obviously different from the other uses of ?.

@FireyFly
Copy link

FireyFly commented Apr 2, 2019

I think other tokens would exhibit similar problems too, e.g. * as a placeholder value near * multiplication and ** exponentiation.

Another approach to solving this down the line, which I think would work with any symbol (even ?), is requiring it to be parenthesized when used elsewhere than as a token in an ArgumentList... e.g. (?).foo(1, 2) for the receiver placeholder case. (Admittedly that still looks a bit funny with optional chaining, but (?)?.foo(a ?? b) isn't that horrible to read, I think)

@ysitbon
Copy link

ysitbon commented Apr 2, 2019

@FireyFly Like the idea of mandatory parenthesis for the receiver placeholder. It fits really well with existing ES design. It also removes limitations listed here: #21 (comment) If it's stated then almost every symbols could be candidates for this proposal.

@FireyFly
Copy link

FireyFly commented Apr 2, 2019

Hm interesting, I hadn't seen that issue/discussion. It seems @rbuckton suggested the same syntax in #21 (comment).

I'm not sure whether my interpretation of the syntax matches the suggestion in that comment.. to clarify, I'm imagining (?) as consuming just another positional argument, just that it can be used in the receiver location as well. I.e. I'd consider (?).foo(?) to be shorthand for (a, b) => a.foo(b).

It's dismissed as fragile syntax in that comment, but I'm not entirely sure why... it seems fairly reasonable to me.

@ysitbon
Copy link

ysitbon commented Apr 2, 2019

@FireyFly Your interpretation was mine. It feels natural to me. And right I forgot about this comment #21 (comment) but I think it should be reconsidered. In fact the not ok part in the example is also fine for me.

@rbuckton
Copy link
Collaborator

rbuckton commented Apr 2, 2019

@FireyFly my concerns about "fragility" were the cases where (?) was not ok, but seemed like it could be, like:

(?).x      // use not part of an immediate call. 
           // If `(?).x()` is ok why isn't this allowed?

(?).x.y(?) // use not part of an immediate call. 
           // Cannot eagerly evaluate `x` for the partial call to `y`.

For these cases you could still use arrow functions:

(a => a.x)
((a, b) => a.x.y(b))

@FireyFly
Copy link

FireyFly commented Apr 2, 2019

Hmm yeah, I could see that. Perhaps it's better to leave it unspecified to begin with, and see whether a lack of receiver placeholder is a problem in practice before specifying it.

@rbuckton
Copy link
Collaborator

rbuckton commented Apr 2, 2019

Please refer to #23 for further discussion.

@rbuckton rbuckton closed this as completed Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants