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

Is it too late to exchange @ / # usage? #84

Closed
hax opened this issue Mar 5, 2018 · 34 comments
Closed

Is it too late to exchange @ / # usage? #84

hax opened this issue Mar 5, 2018 · 34 comments

Comments

@hax
Copy link
Member

hax commented Mar 5, 2018

While it may be too late, but assume we have the chance to exchange the usage of @ and #, aka use @ for private, use # for decorator, it may help the community to accept this proposal.

I know it does not make any difference in semantic, but the feeling of symbol may differ.

JavaScript borrow some notations from CoffeeScript (like arrow functions =>), and CoffeeScript use @x as the shortcut for this.x. Though it does not private, but the heavy usage of @xxx in the class body make it very close to current #priv lexical scope, give us feel it's only for class inner usage. Also, @x as instance variable in Ruby language is private.

Though it's "subjective", I believe there are less people think @xxx is ugly for private field. At least the programmers who have CoffeeScript/Ruby experience can accommodate it soon.

On the other hand, # is used for comments in many languages, and many languages use comments for annotations, which is close to the decorator feature. # is also used as the sigil of compile-time directives in many languages, which close to the decorator's goal of making code more declarative. Consider

#defineElement('my-button')
class MyButton extends HTMLElement {
}

looks not bad.

I did a small investigation to some TypeScript users who use decorators much. They give me positive feedback about using # for decorators. Though it's just a very small sample, I think we could ask the TypeScript community to discuss it.


Exchange @ / # is not a new idea, it may be discussed before. But see the issue list in the repo, at least half issues shows the bad feeling about #priv and try to avoid it hopelessly. I can imagine when this proposal reach stage 4, there will be much more negative feedbacks and many attacks which harmful to the whole JavaScript community.

I suggest we can reinvestigating the possibility to exchange @ and #, thank you.


PS. There is an old Chinese idiom 朝三暮四:

there lived a man who loved taking care of his monkeys... take from food reserves meant for his family in order to keep his monkeys healthy, fat and happy. However, this man’s family eventually began to lose money, meaning that the amount of food this man had to give to his monkeys began to decrease. One night, this man discuss this matter with the monkeys, proposing that he give them three chestnuts in the morning and four chestnuts at night. Upon hearing that, the monkeys began to grit their teeth and growl in anger. The man then changed his proposal: the monkeys would receive four chestnuts in the morning and three chestnuts at night. Hearing that they would get to eat four chestnuts in the morning, the monkeys assumed that their food reserves increased and happily agreed to the man’s conditions.

Yes, in the history of evolution, we are not far from monkeys/apes 🐒

@littledan
Copy link
Member

See previous discussion and TC39 minutes about this proposal.

@hax
Copy link
Member Author

hax commented Mar 5, 2018

@littledan Thank you for the links. It seems we still have chance.

Could revisit later, but it would require a strong argument beyond this.

Could I say the current continual raised issues by many people in this repo is the signal of revisiting? We are already in stage 3, so no much time left?

@ljharb
Copy link
Member

ljharb commented Mar 5, 2018

As the person who tried to get them swapped, i don’t think it’s going to happen.

For example, one of the reasons brought up not to swap is all the existing documentation out there for both private fields and decorators, in JS and TypeScript. To be frank, i don’t think changing that (let alone all the existing code) is going to be considered worth it due to the aesthetic objections of any number of people.

@hax
Copy link
Member Author

hax commented Mar 5, 2018

@ljharb I understand the situation.

I will try to argue three points:

  1. Compare to TS part, I don't think there are much documentation about private field. And the readers should understand proposals will change.

  2. About TS, some breaking changes will eventually happen (semantic change of decorator, or, assume TS must change from @deco export class to export @deco class), we should not afraid too much about documents. With the good help messages of new versions of compilers/IDEs, we can be protected from stale docs. Such thing happened many times in everywhere, eg. Swift languages breaking changes, API incompatibility in new versions of many big frameworks (RoR), etc. Plus, compare to the complex semantic changes, swap sigil is very easy to understand and remember.

  3. I don't think it's only about aesthetic. Or even it's aesthetic, if many people in a community all have the bad feeling, then it will not be just aesthetic anymore. We need to deal with it now, or the community would become full of arguments and conflict when # reach stage 4.


I myself do not have strong opinion in # vs @ issue, but I can see the reasonable factor which will affect the adoption of this proposal. We've seen too much negative, from the first day of #, and increasing, when it from stage 1 to 2 and to 3.

Last year I gave a speech about the private # proposal in a QCon Beijing. Though I believe most audiences finally get the reasons why we need sigil, they still feel terrible to #, especially those who have TS background.

I hope this proposal can land and be success, both JS and TS programmers can use private wisely, in a consistent manner. But in current situation, I worry about it will never happen.

@kenjiru
Copy link

kenjiru commented Mar 12, 2018

Coming from a TypeScript environment, I find the choice of both # and @ as very weird. leaving the aesthetics aside, I find it very confusing to encode meaning in the position of different symbols.

Why not use full words for it? If you don't like private then use some different key word.

@ljharb
Copy link
Member

ljharb commented Mar 12, 2018

@kenjiru please read the FAQ which explains why a keyword is not an option.

@kenjiru
Copy link

kenjiru commented Mar 12, 2018

@ljharb you got me started, I read the FAQ and the TC39 minute regarding this symbol swap. Now I wish I didn't..

I believe that successful projects like Babel and TypeScript should have an influence on TC39, whether some people like it or not.

@bakkot
Copy link
Contributor

bakkot commented Mar 12, 2018

@kenjiru Those projects have a great deal of influence on us. But that doesn't change the fact that TypeScript has a type system and we do not, nor the does it dilute the desire for actual privacy (a desire which the TypeScript team hears quite a bit too).

@Jinjiang
Copy link

Does this.~x work well? To be honest # really doesn't like working code but inline comment anyway. Can't accept it go everywhere in my JS code. 🤦‍♂️
Thanks.

@hax
Copy link
Member Author

hax commented Mar 13, 2018

@Jinjiang this.~x works, but ~x won't because ~ is unary operator (bitwise not). And binary operators like & will introduce ASI. Most symbols have already been taken by unary/binary operators. So the only possible ASCII sigils are @ and #.

@Jinjiang
Copy link

Jinjiang commented Mar 13, 2018

@hax OK well I prefer @ a little more but that's also weird for me.

@shaodahong
Copy link

@ljharb Should listen to user opinions

@jkrems
Copy link

jkrems commented Mar 13, 2018

I believe that successful projects like Babel and TypeScript should have an influence on TC39, whether some people like it or not.

Was that in favor of the current solution? I thought that both TypeScript and Babel implementing @ for decorators is what forced the current trajectory. So, it was Babel/TypeScript that were major influences for this decision.

@shaodahong I'm a user and I don't see a problem with #. I also talked to other users who feel the same way. There's plenty of docs where # is used as a short-hand for "member": http://www.rubydoc.info/stdlib/core/Hash:each_key. So it's not a super unique or unusual choice.

@ljharb
Copy link
Member

ljharb commented Mar 13, 2018

@shaodahong TC39 always does, but user opinions don’t outweigh actual things that will impact users.

@littledan
Copy link
Member

I'd phrase this slightly differently: In addition to considering programmer points of view about issues that are expressed directly, TC39 also considers potential unintended consequences and subtle interactions that might not be apparent to everyone.

@arthur-tacca
Copy link

@hax

# is used for comments in many languages, and many languages use comments for annotations, which is close to the decorator feature.

I find this a quite tenuous. Do you know of any languages where # are used for comments and comments are used for annotations? The fact that some use one or the other isn't really relevant.

# is also used as the sigil of compile-time directives in many languages, which close to the decorator's goal of making code more declarative.

I think you're mostly referring to the #pragma directive in C and C++. I could write an essay on why this isn't relevant, but in the interests of brevity, I'll just say that they're very different beasts and making decorators look like that would be misleading. A closer analogue in C++ is function attributes, which don't use either symbol:

// C++11 standardised notation 
[[deprecated]]
void func1(int);

// Visual Studio non-standard notation
__declspec(deprecated)
void func2(int);

// gcc / clang non-standard notation
void func3(int) __attribute__((deprecated));

If you really want consistency with existing use then the main sources of precedent are Java and Python. Java uses the @ notation for annotations (which like you say are somewhat analogous to decorators) and Python uses the @ notation for actual decorators. In fact Python chose @ for consistency with Java (although the C++-style square brackets were also considered).

@hax
Copy link
Member Author

hax commented Mar 14, 2018

@arthur-tacca

I think you're mostly referring to the #pragma directive in C and C++.

Not only C/C++, also some template languages like velocity use #. Though none of them use # for decorator. But at least they all use# for the features which work in a higher level than normal code, such usages are a little close to decorator than private.


In fact I totally agree your points. My point is it's not which is better problem, unfortunately it's which is worse problem. You have to of two evils choose the less. We already know programmers hate # for #priv, would they be happier with @priv and not much unhappy with #deco? We don't have a confirmed answer, but I (and many) guess/wish they will. 🐒

@Alhadis
Copy link

Alhadis commented Mar 21, 2018

I guess you could say the counterarguments to using #...

... just got POUNDED.

(ooh, that was SHARP)

@xueqingxiao
Copy link

# or @, it's not a big deal for many JavaScript programmers. cause @ has been used for decorator. I think # is fine.

@bschaepper
Copy link

So.. If both @ and # are taken, what's it gonna be for (future not unlikely) protected?

The reasons why we can't go with a keyword are still not convincing to me, even after reading the arguments and FAQ multiple times.

@ephys
Copy link

ephys commented Mar 22, 2018

@bschaepper protected #field would be a possibility. There has been talk about it here and here

@bschaepper
Copy link

@ephys thanks for the links :-) I must say, interessting read. Especially the discussion about making private keyword mandatory, I'd argue, all keywords (public, protected, private) should be mandatory for consistency and clarity.

@Alhadis
Copy link

Alhadis commented Mar 22, 2018

Could somebody brief me on why object#secret isn't being used instead of object.#secret?

@ljharb
Copy link
Member

ljharb commented Mar 22, 2018

@Alhadis because the # is part of the name, the dot is for member access.

@Alhadis
Copy link

Alhadis commented Mar 22, 2018

That's what I'm talking about. Using # as a mechanism for accessing "restricted" members feels a bit more logical than tacking it onto property names:

class Secret {
	#hidden = true;
	hidden = false;
}

Would be analogous to:

class Secret {
	constructor(){
		this#hidden = true;
		this.hidden = false;
	}
}

Think of # as some sort of "restricted scope accessor" or something.

@ljharb
Copy link
Member

ljharb commented Mar 22, 2018

@Alhadis there’s a number of reasons why that won’t work, but they’re off topic for this issue. Please file a new one and we can discuss it there (but please first search to see if there’s a relevant existing issue)

@Alhadis
Copy link

Alhadis commented Mar 22, 2018

Honestly, I don't feel strongly enough about this issue to pursue suggestions to any great degree. I'll leave the bikeshedding to the experts. ;)

there’s a number of reasons why that won’t work

You can tell me at least one, because it seems pretty solidly founded to me. :) I won't derail this thread anymore after that, I promise. ;)

@hax
Copy link
Member Author

hax commented Mar 23, 2018

Think of # as some sort of "restricted scope accessor" or something.

@Alhadis The alternative proposal Class1.1 is exploring this way which use a->b instead of a.#b. You could check it to see if it's what you like.

@Jinjiang
Copy link

Jinjiang commented Mar 23, 2018

@littledan
Copy link
Member

@Alhadis One benefit of using x.#y rather than x#y so that, in the shorthand follow-on proposal, there is no ASI hazard introduced. Another benefit is that the use of . reinforces the analogy with public fields and the idea that # is part of the name of the field.

@d8corp
Copy link

d8corp commented Apr 3, 2018

what about that?

class X {
  .hidden = 1
  test (obj) {
    return obj..hidden
  }
}

@littledan
Copy link
Member

@d8corp This has the same ASI hazard with shorthand. Also, .. isn't really all that evocative, especially as it comes up in other contexts, e.g., 3..toString().

@d8corp
Copy link

d8corp commented Apr 4, 2018

@littledan
thanks, I've not known that.

@littledan
Copy link
Member

At this point, I'd like to settle on the current meanings of @ and #. As for the question of "too late"--I like to think, in general, that Stage 3 is the point where we come to a strong conclusion on these sorts of syntax questions, unless some big new reason comes up, or most of the committee/community becomes convinced by one of the existing arguments. I don't see either of those happening here--I imagine that such a switch will still face the same kind of reluctance as it did the last time it was presented to TC39 (and, in addition, the new argument "didn't we already discuss this and conclude that we're not changing it?").

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