You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 25, 2022. It is now read-only.
TC39 underated the risk of community break which is very harmful to all of us.
TC39 current process failed on such controversial problems.
Some TC39 members use a vicious circle and/or double standards to dismiss the issues/alternatives other raised/offered.
Also, he believes another long wait for private state is acceptable if that's what it takes to get it right: the problems with the current proposal—including with public fields—are just too severe.
Regarding the substance of the proposal:
Duality of private vs. public fields will cause confusion: similar syntax but very different semantics
# syntax does not fit into the mental model of JS devs and will cause a community split, and TypeScript issues will further fracture the community
We don't need public property/field declarations and if we must have them, they should follow existing property semantics instead of fields. Fields cause pernicious bugs when overriding properties in subclasses or refactoring base classes.
Classes 1.1 proposal offers a better alternative in many ways, including instance variable semantics
Similar concerns about the process as @hax. Difficult to understand the committee's requirements and the reasons for them.
"Undetectability" should not be a requirement since it falls short of a fully protective security feature
Strongly believes that the best solution will integrate with existing features instead of crippling or disabling them, e.g. inconsistency of obj['property'] for public fields but no equivalent for private fields breaks existing feature by breaking expectations. Lack of dynamic access of private fields (e.g. this['#x']) is a deal-breaker.
# is not "well-defined"—has two meanings. Context is insufficient to disambiguate declaration and access.
This proposal lacks long-term planning and will irreversibly reduce the design space for important future proposals such as keywords for other access modifiers
Agrees with @rdking that lack of dynamic private properties is a deal-breaker; violates core strength of the JS language (dynamicism)
private #x syntax should be strongly considered because # alone might make future native support of intermediate access levels impossible. But # alone might be OK if we are confident we could have another way of natively sharing private fields within a module.
# being part of the name leads to confusion because this.#x !== this['#x'], it's just too weird. The sigil is fine but the functionality is just too different.
No dynamic access, no destructuring is a deal breaker for me
I agree with @Igmat that "brand-checking shouldn't be added implicitly to all private reads/writes"
I agree with @Igmat that "proposal should allow future native expansion in some way (there are a lot of ways to achieve that)"
I agree with @rdking that "the best solution will integrate with existing features instead of crippling or disabling them."
I believe a private symbol approach (as described in syntax 1 here [Private] yet another alternative to #-based syntax #149) is by far the simplest addition to existing JS paradigms/existing JS class spec, and achieves most of what the current proposal wants with a few minor exceptions (possibility to leak private symbols for one, but I think this could actual be useful for things like protected to be implemented in userland).
Concept "Fields" is unclear and its necessity as an independent concept is questionable. The concept undermines the "Object is collection properties" core concept, and the impact will be extremely far-reaching, but nobody taken seriously. The Similar sound includes: Not Fields in Classes 1.1 proposal.
Using the lexical environment to implement "private field" is to recreate var and ctx's VariableEnvironment, which is an abuse of Environment components, and it is obviously too bulky.
The syntax is very unfriendly, especially with # as a prefix character for declaring fields and for name operations (such as the semantics of this["#x"] vs. this.#x). About grammar, I recommend enabling the private keyword to declare private properties (Note: that I don't support new concepts like "Fields or Private Fields"). And # as an operator, this is reasonable in both this#data and #data as unary or binary operators.
The choice of [[Define]] over [[Set]] for initializers is a bad trade-off that throws away six years of evidence from TypeScript and Babel developers' use of fields. The "natural experiment" has been performed, the results are clear, and the runtime breakage incurred here is very difficult to detect with tooling. The proposed upside of [[Define]] (const fields later) is purely speculative; the downside of not being able to install a deprecation setter is concrete and immediate.
Making initializers on fields optional, especially combined with the above, is unintuitive and dangerous. This syntactic expansion isn't strictly necessary and represents a substantial breaking change problem for TypeScript/Flow/Babel with no clear upside.
Honestly, the negative response to the # sigil is something we should just ignore and take the hit for, if built-in hard privacy is really needed. People will adapt and the runtime need for it is extremely clear; all counterproposals have been ignorant of the design constraints or runtime semantics.
my main objection to the current private fields proposal (and more so private methods) is that it throws away the notion of prototypal inheritance in favour of an object branding mechanism inconsistent with how other properties work.
In addition, some members of the TC39 committee also have current objections to this proposal. For example:
See the Classes 1.1 motivation document. In particular if you negate the descriptions in the Design Rules bullet list you have a good summary of my concerns with the major problems being:
Design Rules:
Item 2:
Be as small as possible
Item 3:
Support a user conceptual model that is as simple as possible. It should be easy to teach and easy to understand.
Item 4:
Be internally consistent, with few, if any, special cases or unexpected feature interactions.
I believe that we are overpricing the benefit of this entire feature set while underpricing the risk.
Why do I think that we're overpricing the benefit?
In my experience, most of our constituency does not need hard-private in their day-to-day programming work. Hard private is important for a small number of use cases, such as platform library code and high-profile libraries which are especially subject to breaking consumers when implementation details are updated. Most application programmers I know don't write that kind of code. Sorry 🤷♀️
Folks that really want "fields" are mostly happy using TypeScript already. It doesn't seem implausible to me that TS could have an option for generating hard-private code for private x, perhaps with some optimization work applied to WeakMap on the engine side.
Why do I think that we're underpricing the risk?
We know that many devs don't like the syntax, and don't understand why the syntax that they enjoy using (private x from TypeScript) won't work. It doesn't "just work". We are taking on the risk that this feature will continue to create head-scratching across our community.
We're taking on the risk that we'll want # for something else and it won't be available.
We're taking on a small amount of ASI risk.
We're taking on a risk that by pushing something unpopular our community will lose some amount of faith in TC39 and the future of JS.
I probably missed something important, and obviously I haven't included a summary for everyone who has commented. If you feel something is missing, please provide a concise summary of your feedback as your first comment on this thread (saving longer arguments for subsequent comments). Also feel free to simply say, "I agree with [username]".
Continuing from #100 and other threads, here's a summary of key objections to this proposal raised by the community:
@hax's top 3 concerns:
Also, he believes another long wait for private state is acceptable if that's what it takes to get it right: the problems with the current proposal—including with public fields—are just too severe.
Regarding the substance of the proposal:
#syntax does not fit into the mental model of JS devs and will cause a community split, and TypeScript issues will further fracture the community@rdking:
obj['property']for public fields but no equivalent for private fields breaks existing feature by breaking expectations. Lack of dynamic access of private fields (e.g.this['#x']) is a deal-breaker.#is not "well-defined"—has two meanings. Context is insufficient to disambiguate declaration and access.@bdistin:
@mbrowne (me):
(NB: it's mbrowne, not mbrown)
private #xsyntax should be strongly considered because#alone might make future native support of intermediate access levels impossible. But#alone might be OK if we are confident we could have another way of natively sharing private fields within a module.@Igmat:
brand-checkingshouldn't be added implicitly to all private reads/writes, since it breaks metaprogramming with proxies as described in Private members break proxies #106 and [Private] Metaprogramming vs Security #134Symbol.private+ some kind of shorthand syntax for making symbols more ergonomic, provides much cleaner mechanism for encapsulation@shannon:
#being part of the name leads to confusion becausethis.#x !== this['#x'], it's just too weird. The sigil is fine but the functionality is just too different.#-based syntax #149) is by far the simplest addition to existing JS paradigms/existing JS class spec, and achieves most of what the current proposal wants with a few minor exceptions (possibility to leak private symbols for one, but I think this could actual be useful for things like protected to be implemented in userland).@aimingoo:
varand ctx's VariableEnvironment, which is an abuse of Environment components, and it is obviously too bulky.this["#x"]vs.this.#x). About grammar, I recommend enabling theprivatekeyword to declare private properties (Note: that I don't support new concepts like "Fields or Private Fields"). And # as an operator, this is reasonable in boththis#dataand#dataas unary or binary operators.Reference: #148 , #100 (comment)
@RyanCavanaugh:
[[Define]]over[[Set]]for initializers is a bad trade-off that throws away six years of evidence from TypeScript and Babel developers' use of fields. The "natural experiment" has been performed, the results are clear, and the runtime breakage incurred here is very difficult to detect with tooling. The proposed upside of[[Define]](const fields later) is purely speculative; the downside of not being able to install a deprecation setter is concrete and immediate.#sigil is something we should just ignore and take the hit for, if built-in hard privacy is really needed. People will adapt and the runtime need for it is extremely clear; all counterproposals have been ignorant of the design constraints or runtime semantics.@Jamesernator
In addition, some members of the TC39 committee also have current objections to this proposal. For example:
@allenwb:
Design Rules:
Item 2:
Item 3:
Item 4:
@zenparsing:
private xfrom TypeScript) won't work. It doesn't "just work". We are taking on the risk that this feature will continue to create head-scratching across our community.#for something else and it won't be available.I probably missed something important, and obviously I haven't included a summary for everyone who has commented. If you feel something is missing, please provide a concise summary of your feedback as your first comment on this thread (saving longer arguments for subsequent comments). Also feel free to simply say, "I agree with [username]".