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

Why -> is any better than .# #19

Closed
allenwb opened this issue Mar 5, 2018 · 24 comments
Closed

Why -> is any better than .# #19

allenwb opened this issue Mar 5, 2018 · 24 comments

Comments

@allenwb
Copy link
Collaborator

allenwb commented Mar 5, 2018

In response to @BrendanEich #17 (comment)

  1. there has been very strong community push back against # as a private name prefix.
  2. .# is not a single token but is the . operator followed by a #prefixed identifier. The implication is that . is the primary operator.
  3. But . is not appropriate because the semantics of referencing a hidden name (as defined in this proposal) are not the semantics of property lookup. This will likely lead to more conceptual confusion about the nature of instance variable, hidden methods, and properties.
  4. Using a distinct operator to dereference a hidden name should help diminish such confusion.
  5. There is a limited set of available ascii special characters available for new operators. -> is an available character combination that carries along a referencing implication from C/C++.
  6. Another possible operator is ... It may be perceived as similar, but different to the . operator. There are both positive and negative conceptual implications of that similarity.
  7. I think -> reads better (stands out more). See the example at the start of AWB alternative proposal sketch #1 #5.
@littledan
Copy link
Collaborator

But . is not appropriate because the semantics of referencing a hidden name (as defined in this proposal) are not the semantics of property lookup. This will likely lead to more conceptual confusion about the nature of instance variable, hidden methods, and properties.

This seems like a really core part of the argument. Why do you think -> will create such different intuitions? In C++, for example, it is basically the same as . just with a dereference (modulo crazy operator overloading). Even ignoring other language precedents, it's still "getting a thing out if a thing" and people might imagine that it's the same.

On the other hand, the private fields and methods proposals have been designed to be basically parallel to public properties in their semantics, and make this mental model that they are related practical for writing code.

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 6, 2018

Why do you think -> will create such different intuitions? In C++, for example, it is basically the same as . just with a dereference (modulo crazy operator overloading).

I don't think the actual semantics of the C -> operator is very relevant.

But, to turn your question around. Why would a JS programmer have an intuition that -> and . have similar semantics? They are visually distinct operators? If they were closely related, why wouldn't they look the same? This is discussed in more detail in #9

@littledan
Copy link
Collaborator

You are right, the semantics of the C/C++ -> operator are not very relevant. However, semantically, both operators . and -> have to do with reading/writing named things that relate to an instance. I don't think it's a stretch of the imagination that, sometimes, when you're working with multiple namespaces, you might get confused between the two, even if the namespaces are semantically different.

@zenparsing
Copy link
Owner

I don't think it's a stretch of the imagination that, sometimes, when you're working with multiple namespaces, you might get confused between the two, even if the namespaces are semantically different.

I don't think there's a terribly high risk of confusion over which operator to use, once the rule is learned ("for hidden things use ->"), but I do agree that there is a risk that users will experience typos where they intend to type -> but instead type . out of muscle memory habit.

@allenwb Another option which I didn't think about before is ::, which might help to convey that the RHS name is lexically-scoped (and reserve -> for other future usage). Any thoughts?

Here are the examples, written with ::.

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 7, 2018

@zenparsing

I think that -> and :: are equally good from the perspective of being visually distinct from '. I actually don't have a strong preference for one over the other. The distinction between -> and :: is probably meaningful for people coming from C++. At this point and going forward, I'm not sure how how large a part of the total JS programmer community that actually is.

However, won't the proponents of the bind operator proposal 😜 get pissed off if we try to take ::. More seriously, which choice is likely to be less controversial?

@zenparsing
Copy link
Owner

However, won't the proponents of the bind operator proposal 😜 get pissed off

Are there any of those left out there? I think the chaining aspect of that proposal (which was always a little sketchy) has been overtaken by |>. And after thinking about it for a while, I don't think a binary :: works for method extraction, because you'll want to be able to extract a symbol-named or a hidden-named method. And the prefix version of :: is just plain weird.

We need a solution for method extraction (probably some kind of a unary operator), but I don't think :: is it.

@zenparsing zenparsing changed the title why -> is any better than .# Why -> is any better than .# Mar 8, 2018
@BrendanEich
Copy link
Collaborator

BrendanEich commented Mar 9, 2018

JS programmers include those who know C and C++. If this proposal uses ::, my gut says that we are in for more hurt than would come our way over ->. But both will excite comments and neither gives a shorthand free of semicolon issues.

An observation regarding item 2 in the list for this issue: .# could be one token, and maximal munch means no ambiguity. The shorthand would use only # as prefix to avoid semicolon issues. obj . # foo and variations with space between dot and hash would be a syntax error.

This could solve the "dot is for property" objection (item 3). I wanted to record it so we discuss and avoid overlooking a path that does not proceed down the dot-means-property path based on the assumption (choice) of .# as two tokens, dot operator and hash prefix.

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 9, 2018

Or #. which might further conceptually distance it from property access.

However, I still think that # doesn't have a good intuitive feel in this context plus # is so attractive for other uses.

@BrendanEich
Copy link
Collaborator

What are other # proposals? I haven't seen any.

@zenparsing
Copy link
Owner

What are other # proposals? I haven't seen any.

There is some experimentation going on with the pipeline proposal, where # is posited as the "pipe value" sigil.

tc39/proposal-pipeline-operator#100

But I also worry about any usage of # related to "private state" given the community response.

@BrendanEich
Copy link
Collaborator

I think the reaction to # is negative for any use. It's hard to separate concern re: private vs. general, though. Anyone have a twitter poll or better?

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 9, 2018

I wasn't thinking about any specific proposal for #. But I did have in the back of my mind the possibility of using it for new literal forms. I believe in the wiki days some such proposals were floating around.

@BrendanEich
Copy link
Collaborator

BrendanEich commented Mar 10, 2018

Lol, I should have remembered, as I was the one who proposed #{p:1, q:2} and #[1, 2, 3] first -- remember "Harmony of my dreams"? I recycled short term memory because I had given up, but I shouldn't have -- the # function form is sweet!

Ok, I agree: -> is better for private in part because it does not claim hash.

@littledan
Copy link
Collaborator

From a grammar standpoint, I don't think we have to worry about # being "claimed"--there'd be no ambiguity about supporting both private field shorthand and frozen object/method syntax since you can't begin a name with [ or {.

I don't think there'd be ambiguity if we supported # for placeholders in the pipeline and/or partial application proposals, except possibly with the frozen object syntax if we wanted to allow "partial application" for the receiver of a symbol-named method. But this would only be between those two proposals, and not with the .# private field syntax. Keith Cirkel's {# #} syntax (which I really like! but I might've been the only one in the committee) would get around the issue.

It's true that the combination of these things would make # semantically overloaded, but at this point, basically every existing symbol has multiple usages too. I don't know whether it's better to have longer tokens with more punctuation characters, or short tokens that are multiply used--probably better for someone with more distance from the proposals than me to evaluate (since to me it seems fine to overload).

Anyway, if the big issue is the syntax, that maybe the community would find -> to be much more ergonomic than .#, should we consider just changing that syntax and nothing else?

I don't know if I really buy the hypothesis that avoiding the . is key to enabling people to think outside the box about the semantics--I think they're about equal in terms of intuition for whether things should correspond 100% to ordinary property access (we will have to explain that it doesn't either way, and some people won't like that). Hopefully we can get more feedback which lets us sort of test this hypothesis. If it turns out that this choice of token doesn't affect intuitions about semantics for most of the people we hear from, then I think we should consider the syntax change orthogonally from the other changes that this repository proposes.

@zenparsing
Copy link
Owner

Anyway, if the big issue is the syntax, that maybe the community would find -> to be much more ergonomic than .#, should we consider just changing that syntax and nothing else?

Probably not, if fields are kept as the starting point. As I argue over in #21 , when fields are taken as the starting point, you naturally end up with "private fields" and "private methods" which introduce many of the problems that this proposal attempts to avoid (including the need for leading-sigil names).

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 10, 2018

Right, we aren't just trying to fix the # controversy. This is more an an exercise to see if we reduce complexity by maximally minimizing what need to be added to class definitions.

@zenparsing
Copy link
Owner

Closing in preparation for public review. Please feel free to continue discussion or open a new issue for a specific topic.

@ephys
Copy link

ephys commented Mar 13, 2018

But . is not appropriate because the semantics of referencing a hidden name (as defined in this proposal) are not the semantics of property lookup. This will likely lead to more conceptual confusion about the nature of instance variable, hidden methods, and properties.

Would such confusion be an actual issue? Do you have an example of something that might not work as expected for a JS developer?
One source of issues I can see is trying to dynamically access a hidden name but I'm pretty convinced developers are going to try to do it with this syntax anyway.

Also, IMHO -> feels like an alias for ., especially given that other languages use it that way. Whereas prefixing with # is closer to current community conventions for private state (prefixing with _).

I don't have any data on this but another potential downside is that we'll now have to remember if the property we're trying to access is private or public and use the corresponding operator. An issue # doesn't have (mainly thanks to autocompletion).

@hax
Copy link
Contributor

hax commented Mar 14, 2018

@ephys

but I'm pretty convinced developers are going to try to do it with this syntax anyway.

Why programmers want to try this['->x'] and expect it return same thing of this->x? Or do you mean they will expect this['x'] return same thing of this->x? It's very unreasonable because we already know this.x is same as this['x'], so if this.x is same as this->x, what's the purpose of introducing ->? I don't believe any experienced programmers will think like that.

Also, IMHO -> feels like an alias for .

If this is your only concern, what do you think about :: as a replacement of ->? We also can consider ~> or ~. Whichever we choose I believe the syntax issue of this proposal is much much smaller than #priv.

Whereas prefixing with # is closer to current community conventions for private state (prefixing with _).

Unfortunately programmers never think # like _. We already see the problem of # is not technical, but cultural, mental and aesthetic. I gave a speech introduce #priv last year in programming language track of QCon, and most audiences feel terrible with #...

we're trying to access is private or public and use the corresponding operator. An issue # doesn't have (mainly thanks to autocompletion).

This is a minor ergonomics problem of writing code, I don't think it's a big deal, and autocompletion also apply here -- when you enter this, autocompletion can list all properties/methods/vars/hidden-methods and other bindings start with this.

@wycats
Copy link

wycats commented Mar 16, 2018

Sorry for jumping in late; I didn't see this repository before it was made public.

Most of my programming experience is with Ruby, JavaScript (with some TypeScript) and Rust, so I personally don't have a visceral feel for the -> operator from significant usage in C or C++.

That said, as @littledan suggested, x->y evokes a similar "containment" relationship:

However, semantically, both operators . and -> have to do with reading/writing named things that relate to an instance.

More specifically, x->y does not suggest to me that y is a lexical variable that is being used as a way to look up a value associated with x. The x.#y syntax doesn't fare better for me on this front, but this proposed syntax has roughly the same problem for the same reason.

@hax
Copy link
Contributor

hax commented Mar 16, 2018

@wycats

but this proposed syntax has roughly the same problem

We always have to choose one syntax... from this not long 😉 list:

  • this.@x Ruby/CoffeeScript style (though it seems very unlikely to happen)
  • this.#x Current field proposal
  • this->x C/C++/PHP style
  • this~>x Variant of ->
  • this::x @zenparsing alternative
  • this..x @allenwb 's old double dot style
  • this~x Reuse the forgotten token ~ as a binary operator

Which one (or two) do you prefer?

@allenwb
Copy link
Collaborator Author

allenwb commented Mar 16, 2018

@wycats

The x.#y syntax doesn't fare better for me on this front, but this proposed syntax has roughly the same problem for the same reason.

From a purely technical perspective , .# as a single token infix operator is equivalent to ->, ::, or any other infix operator symbol. But the current proposals define .# is a two token sequence where # is prefix character to an IdentifierName. There has been really strong community push back against that prefixing. The concern doesn't appear to be just with the specific # character choice. There also appears to be a fear that this is just first step towards a family of such name prefixes in the style of BASIC.

Even if we defined .# a single token infix operator, that perception would probably persist.

One of our reasons for choosing an operator that doesn't include . is because, as you point out, the treatment of the name to the right of -> is different then the treatment of the name to the right of .. Neither -> or . are really infix operators. Instead, both are special forms that impose non-expression semantics on what follows to their right.

A symbol that implies containment is nice, but is unlikely to be universally recognized as such. Ultimately, people have to learn the semantics of these special forms, and intuition is only going to carry them so far.

@ljharb
Copy link

ljharb commented Mar 16, 2018

There also appears to be a fear that this is just first step towards a family of such name prefixes in the style of BASIC.

@allenwb can you point me to a corpus of pushback that reflects that fear? I've seen, almost universally, a simple dislike of the "#" because it's "ugly". I also don't think that regular developers have a strong sense of "how many tokens are in a sequence" or "somethingfix operator".

@hax
Copy link
Contributor

hax commented Mar 19, 2018

@ljharb
Yes people don't matter "somethingfix operator".

But # in #x is not a operator. When you mean operator, x in !x should convey the same meaning of x in #x. But it's not, #x should be understand as a special identifier which very different to x. I think this bring people a big strangeness.

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

No branches or pull requests

8 participants