Closed Igmat closed 5 years ago
I'm wondering, how would people feel about discussing private symbols in @jridgewell's repository, and focusing this repository on discussing this class fields proposal?
First of all, that repo is a fork, so creating issues isn't allowed (or I don't know how to create them?).
And second is that two different types of privacy doesn't have much sense.
Sounds like the lack of ability to make issues is something that should be fixed. Until then, maybe you can discuss things on @zenparsing's repository.
I agree that it'd be overkill to have multiple kinds of private. This repository is pursuing one proposal in that space, whereas that proposal is discussing another kind. We can have issues in both places, with the discussion sorted by which proposal you're working on. In TC39, the champions of each proposal can discuss the pros and cons of each, informed by the discussion in issues in their repository.
@littledan, I got your point. I obviously could put syntax discussion to that repo. But what is more important in this particular case is my questions regarding status quo
of this class-fields
proposal. And your thought about steps I proposed. I think that it makes much more sense to discuss them here, don't you agree?
OK, to clarify, I don't plan to pursue your proposal. We had lengthy discussion about whether we should include prefixes like public
in field declarations, and decided not to.
But it's not a field declaration, it's symbol declaration.
I proposed shorthand syntax for all kinds of Symbols, anywhere in the code. class
example is here just to show how it interacts with classes. public
/private
keywords used to declare Symbol, not field, and my proposal has no affect on existing class-fields
proposal (except I'm asking to move private
part from it).
Anyway, syntax discussion could be omitted (or moved to another repo), but action items is still here (e.g. @zenparsing's Symbol literals
could be used as well).
So what about answering to this part?
- Move
Symbol.private
tostage 1
- Remove
private
part of existingclass-fields
proposal, but leave it instage 3
and normally proceed it tostage 4
whenever committee decides it's appropriate timeProceed with shorthand syntax for
Symbols
(this one, or @zenparsing's, or any other I mentioned before)
- as a follow-up proposal for
symbol-private-proposal
- as a part of
symbol-private-proposal
I'm ready to create all needed documents for it (e.g. changes to spec, readme, faq, etc.) and polyfill + transpiler plugin
To answer your question, I don't plan to work towards any of those bullet points, including working on a proposal for syntax for symbols. We've discussed the reasons for this at great length in various other issues. Feel free to write a proposal and collaborate with other TC39 delegates and community members to work towards these goals.
What's really,
about the proposal of this issue is that it works outside of class
es, which makes it much more dynamic (f.e. easy to implement "friends" or other such features using it), and it can still achieve the same as what the "private" feature of class-fields proposal of this repo wants to achieve.
Plus,
_.pick(obj, #y, #x) // gives the lib access ONLY to #y and #x
in contrast to my idea in another thread (which isn't that bad anyways, use trusted libs),
_.pick(obj, 'x', 'y', private) // gives the lib access to ALL privates
We should use libs that we trust anyways.
@Igmat There's one thing I'm missing in your examples: how does inheritance work with public [#y] = 1
? How does the code in a subclass of a class
in another module, or the code in a module that imports an object literal that has the public [#y]
, access the properties? (I'm also curious about protected
inheritance, which would probably be similar.)
Is there a syntax we could use so that names can be accessed as strings, so that it can be even more interoperable with existing libs?
I don't plan to work towards any of those bullet points
@littledan It'd be awesome if you worked towards considering the pros/cons of what's offered here, rather than simply dismissing it.
The growth of JavaScript is on an exponential curve it seems, and @littledan your proposal is (IMO) caught right in the cusp (new features like WASM are helping to propel JS even faster): the point prior to which community discussion was limited, and after which growing community involvement has shown that the private proposal in this repo is largely disliked by the community, but maybe not for good reasons (I explained in the other issue about future add-ons).
The right thing to do is to consider the new landscape and new possibilities (like in this issue), give them an honest chance, and delay private properties for a while longer to get the spec just right before it is embedded in stone.
Because we're in the cusp, any slow down from changes to the spec aren't going to drastically delay the release of private fields. Suppose it takes another year or two extra: that's not so bad considering the age of the discussion (at least more than a decade from my limited knowledge).
A lot of people really want this feature, and want it to be robust.
Random thought: adapting from here and :private
and :fooPriv
from examples in #205, it could be possible that visibility helpers can be created for POJOs in such a way that allows regular .
and []
access:
const priv = Symbol.private()
export const obj = {n:1}
obj:priv.foo = 1
obj:priv['pro'+'perty'] = 1
// Object.keys method is updated to take a second arg, the visibility helper
Object.keys(obj, priv) // ["foo", "property"]
const o2 = { ...obj:priv }
Object.keys(o2) // ["foo", "property"]
const o3 = { ...obj, ...obj:priv }
Object.keys(o2) // ["n", "foo", "property"]
import obj from './obj'
Object.keys(obj) // ["n"]
const priv = Symbol.private()
Object.keys(obj, priv) // []
I see
Symbol.private
as viable alternative to the wayprivates
presented in existing proposal. Most of you probably knows such position of mine.Most of the time
Symbol.private
was a rejected because of:Membrane
pattern[[InternalSlot]]
1 - is solved in #183 2 - could be easily added by one simple decorator, when really needed, in case of
Symbol.private
. While being implictly added to highly required on its ownencapsulation
feature (as in existing proposal) leads to unsovable problems like #106, especially for metaprogramming libraries'/frameworks' authors (like me, Vue.js, Aurellia, etc.) 3 - while its questionable why should encapsulated state work in same way as internal slots at all, if it really needed, then solution for this question is easy - lets useSymbol.private
instead of[[InternalSlot]]
4 - I'll provide solution for this in this particular thread (I hope it will be final one, since I already provided quite a few)Just for history
Lists of already suggested shorthand sytnaxes for
Symbol.private
. Class only:149
134
For all symbols:
Symbol literals
, but I got this idea independently and it has few differencesSyntax
Declaration
Use
public
,private
(protected
as follow-up) as declaration keyword, likevar
/let
/const
.Assigment
Any assignment without receiver leads to early SyntaxError
Proper assignment always has receiver,
[]
and has no keyword.Declaration + computed property syntax in object literals
The true power comes with computed property syntax.
Declaration + computed property syntax in classes
Work mostly the same way as for objects.
Simple mental model
#
stands forSymbol
. Any variable starting with this sign is ALWAYSSymbol
. So code like thisprivate #x
should be read asprivate symbol x
.Discussible moments
I used already reserved keywords, since we are safe to use them + they are good fit for such mental model. But, obviously, we could select some others, for example:
Possible follow-up proposals
Symbol.protected
/Symbol.friend
/Symbol.<whatever>
and<whatever> #x
declaration syntax;<whatever> #x for 'key'
as shorthand forconst x = Symbol.for('key')
;Conclusion
It seems to cover most important ergonomic cases for
private
at classes. If you see any other important but still not covered cases or have any questions to this syntax feel free to ask/advice/discuss them here - I'm open to futher adjustments and believe that it could be improved in a way that will work for committee (if it's not there yet).Proposal for futher steps
Symbol.private
tostage 1
private
part of existingclass-fields
proposal, but leave it instage 3
and normally proceed it tostage 4
whenever committee decides it's appropriate timeSymbols
(this one, or @zenparsing's, or any other I mentioned before)symbol-private-proposal
symbol-private-proposal
I'm ready to create all needed documents for it (e.g. changes to spec, readme, faq, etc.) and polyfill + transpiler pluginAlso, I want to mention that our
small but vocal group
(me, @rdking, @shannon) has consensus on it and sees such approach as the best possible way to solve majority of existing problems. Probably @hax and @trusktr also share this position, but I'm not sure.Does it make any sense to you (@ljhard, @littledan, @erights, @jridgewell, @zenparsing, @bakkot, @syg)?