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

Final change suggestion #25

Closed
rdking opened this issue Jan 17, 2018 · 4 comments
Closed

Final change suggestion #25

rdking opened this issue Jan 17, 2018 · 4 comments

Comments

@rdking
Copy link

rdking commented Jan 17, 2018

@littledan This thread will contain the last suggestions I'm going to make. I'm taking into account your issue with [] being "two completely different meanings... punned onto the same token". My new suggestion is a compromise. You've currently got 3 completely different meaning punned onto #. If my approach is bad in your eyes, your's is logically worse. So try this:

  1. Don't use internal slots. Keeping class as syntactic sugar should be a primary goal.
  2. Let # act only as a "private scope access" token. That way it has exactly 1 meaning in the context of a class.
  3. Use private #name for declarations. Since the sigil is a "private scope access" token, it cannot be used alone to declare, hence private.
  4. No shortcut syntax (#x) for access notation. Consider that if a variable is not declared, but used within a particular scope, it is treated as though it extends [[Global]]. Since # cannot declare, by default it would try to access [[Global]].#x which does not exist and cannot be dynamically created, especially since it's outside of any class definition of [[Global]] would need to be, but wouldn't be an instance. Thus, naturally a TypeError.

These 4 changes to your proposal would directly address all but 1 of my objections to your proposal. The last issue (the use of this.#x without allowing either this["#x"] or this[#x]) is indirectly resolved by (2). Since the # is a "private scope access" token, this.#x resolves to this.[[PrivateScope]].x. As such, the key name "x" is on the [[PrivateScope]] which is inconsistent with this["#x"] where the key name is "#x". Further, since with this[#x] the key name is not a string, but an impossible variable name due to (4), it is also invalid. This means the new suggestion is completely in keeping with your proposal and objections while removing the issues I outlined in my previous suggestion.

@bakkot
Copy link
Contributor

bakkot commented Jan 17, 2018

The shorthand syntax (your 4) was removed from the proposal a while back, and the suggestion of having declarations be private #foo was discussed at some length here and ultimately rejected by the committee on mainly on the basis that it's entirely redundant as soon as you've learned that #-prefixed fields are private, which you have to learn when using the feature anyway.

Also, personally I quite like the symmetry in class A { x = 0; #y = 1; m(){ return this.x + this.#y; } }.

@littledan
Copy link
Member

I share @VAlley's analysis here.

@littledan
Copy link
Member

@bakkot's analysis (autocorrect)

@rdking
Copy link
Author

rdking commented Jan 17, 2018

@bakkot I'm happy to see (1) & (4). As for the remaining suggestions, no one on the thread you linked mentioned an argument in favor of (2). If (2) were accepted, (3) would be a natural requirement. The argument in favor of (2) has to do with the changes (that I'm sure you've already coded in v8) to variable declaration semantics.

............ you know what?

I argued myself into a corner that I couldn't get out of logically when thinking about (2). The overloaded meaning for # is unamiable, and breaks with the ES convention of having a keyword prefix for all declarations that aren't defaulted global (class, let, var, function, ...). Furthermore, class already uses modifier keywords (static, get) for properties that aren't simply public. However, beyond the distaste for the asymmetry, I can't present any logical reasons or issues that would make it more logically desirable to accept (2).

Oh well. ¯_(ツ)_/¯

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

3 participants