-
Notifications
You must be signed in to change notification settings - Fork 113
Symbol.private vs WeakMap semantics #183
Comments
Yes. Proposals will not gain consensus if they break membranes.
Not all of them, see below.
"Ergonomic syntax" meaning something like
I think most of the committee likes Membrane stuff:
There's a few more like this, but you're getting close. A big issue is all your proxy handlers will fail "has" checks, since you're using |
@jridgewell thank you for response. I guess it's a good start for constructive discussion.
I also just get an idea how to create runnable tests that emulates |
@Igmat thanks for creating a self-contained issue. I will respond here. I would like to indicate by when, but I've already exceeded previous expectations --- my apologies. |
@jridgewell, @erights I just realized that I accidentally broke layout of my answer in #183 (comment). I updated the comment, so my points become visible - you probably may review it since those answers could be helpful for understanding. |
Ahh, I didn't see that. I'm not sure how Mark feels about it, but that's not the membrane design as I understand it. On the left side and right sides, values shouldn't be wrapped. Only a left-sided object pulled through to the right side should be wrapped (and the other direction too).
I'm not sure I follow. The code I'm thinking of is
Yah, I have a feeling it's like a 90% requirement. Not strictly necessary, but the committee likes it enough that it must be a very, very good reason not to include it. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Sorry for the delay (Christmas and New Year holidays takes too much preparation =/), but continuing the topic. As I promised, here a little test project for Important notes:
Next steps:
@erights, @jridgewell, @jridgewell, @littledan does it help? Do you have any comments about it? |
@erights, @jridgewell, @littledan I updated my Big thanks to @jridgewell with his help explaining some points I missed and providing better test suites. |
I am sorry about the delay in these reviews. I want to just point out that a single slide might include constraints that are considered important, but might not be exhaustive, so an implementation passing certain tests might not be sufficient. I think we had some pretty specific reasons for each aspect of the WeakMap semantics in this proposal. I wrote some notes about it in https://gist.github.com/littledan/f4f6b698813f813ee64a6fb271173fc8 . This might turn into a TC39 presentation if private symbols semantics are re-raised to the committee. |
@littledan Would it be fair to say that the document you've got at that link is at least somewhat representative of TC39's desires for a private data proposal in general? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I'm wondering, would folks here be interested in moving the discussion to @zenparsing's repository on private symbols? I don't plan to champion private symbols, and so working out the details in this repository might be misplaced effort. |
Yes, that's the case. They're checked only on access, not invocation.
It wasn't dropped because of problems for engine implementations, but rather because it was a refactoring hazard, as you identified. I consider the check on access to be much more important than a check on invocation would be.
It's always possible, but I think the current state will be less likely to lead to such situations than most possible alternatives. |
@littledan, sorry, but since |
I've been clear in this issue thread about my reasons for pursuing this proposal rather than private symbols and my expectation that private symbols will not get consensus in TC39. We've also been in contact by email about how to improve community outreach in TC39, and I look forward to working with you on the meetup in Minsk. I'm not the right person to cheer you on in your continued discussion of private symbols, but feel free to work with @jridgewell and @zenparsing on this effort. |
@bakkot You picked on the semantics of "method" but didn't address the elephant in my post 😄 Let me state it more explicitly: the hash-stuff part of this proposal doesn't carry it's (significant) weight. I think it should be separated out from public fields. |
The fields proposal has already been merged, split on new lines, and re-merged, with consensus. Can you share the arguments you think would make it more likely for such a change to attain consensus? |
OK, we're getting pretty far off-topic of Symbol.private vs WeakMap semantics. What do you all think we should do with this issue? I don't know how productive it is to have an general purpose chat room to continue repeating ourselves in. |
@zenparsing Sorry, let me respond explicitly, then, though I imagine you know my position. I think your hidden-state library is great, but (as a user) I don't think it's anything like a substitute for language-level support for privacy, and the addition of some syntax sugar would not be enough to bridge that gap. And I'm confused by the implication that it would solve any of the semantic concerns that people have with this proposal, since it has almost identical semantics including interactions with proxies and so on. Or am I confused about what you're proposing? And, separately, I think it's a very bad idea to develop public fields in a different proposal from private state - after having gone through that process, I think it ought to be clear that many of the design decisions are at least sometimes closely linked. If we're revisiting private state, I think we would also have to retract public fields. |
@littledan I don't think it does much harm to let the discussion continue here, despite being somewhat off-topic for the original purpose of the thread (and despite the fact that identical discussions have been happening for a decade). It may or may not be especially productive, but I don't think we need to shut it down unless the OP wants to keep the issue on-topic or it gets particularly acrimonious. |
Perhaps this will clarify: I don't think developers should be encouraged to use hard private state in their workaday abstractions. For those that need it (polyfills, platform code, high profile libraries...maybe) "hidden-state" or something like it is good enough. For most code, soft private via symbols, with some syntactic support, is a better solution (b/c it doesn't suffer from all of those "hard case" issues). We can develop that separately from the (public) fields proposal. |
@zenparsing Hm, ok. We've talked about that a lot, and I understand why people hold that position. But since we've talked about it a lot, I imagine you know that I disagree (rather strongly); I think all developers ought to be explicit about what their public API is, and it's pretty clear that anything shy of actual privacy will be considered by a fairly large fraction of developers to be a de-facto public API. (Not just in the obvious adversarial situations - this comes up a fair bit between two sufficiently separated teams within individual companies developing purely internal code, leaving us with this sort of thing.) I know a lot of the committee shares this position. I don't know how we can reconcile this. We have to pick one - either the language encourages hard privacy as a first-class feature, or it doesn't. What can we do from here? |
I disagree very much; i think almost all code needs hard private - there are a long list of issues caused by soft private that already occur in the ecosystem, and have for decades - other than Proxy, i haven’t seen any problems in the wild from using hard private (which includes all variables closed over by functions). |
This is pretty untrue, or at least only true for your current job. It's not true for all of what I have written, and my current job. I'm raising my concern one more time: my moderately paid job, on a Friday afternoon with a production bug introduced by my coworkers who are not TC39 or any kind of JS experts, with the help of all the issues caused by enforcement from this proposal, will make me very miserable. Maybe I should get better job, but that's a different story. |
@bigopon, the claim is that bugs of that kind will be less likely if the language supports hard privacy as a first-class feature - that is, if it enforces that classes are used only according to the public API the author intended, rather than the public API they as non-experts accidentally introduced, not realizing that was what they were doing. This is very much the same as the design of closures. |
The downsides of hard private being the default (with the associated syntax) are well documented. I believe that:
|
Well, yes. As you know I and a number of other committee members disagree with all three of those points. We've talked about them all (excepting the third, insofar as your specific vision is fairly recent) at very, very great length. Again, what might we do from here? |
@zenparsing Notice you said "vast majority of application developers"? Doesn't that mean that there are those of us who would benefit from hard private support? The "vast majority" of developers don't write libraries. However, the "vast majority" of developers are library users. If that small minority is the library developers, then won't the "vast majority" still benefit from a feature needed by the small minority? |
I'm closing this issue, as we have been having an unstructured conversation about all aspects of several class proposals, on points which have been made repeatedly elsewhere, rather than discussing the topic of this issue. I encourage folks who are interested in private symbols to develop them in the private symbols repository and @jridgewell 's fork. We'll use this repository to develop the WeakMap-based class fields proposal. |
For @bakkot |
@zenparsing As long as the language continues to exist, either it will or will not encourage hard privacy as a first-class feature. There's no "not to play" option other than burning the language to the ground. And burning the language to the ground seems not to be an option at the moment, so... |
@bakkot Not playing does not necessarily mean not encouraging hard private. It can also be the position that the language already has adequate mechanism to support hard private, and that the status quo is a better way to support hard private than any of the mechanisms we propose to help support it. For example, all the examples at https://github.com/erights/PNLSOWNSF/blob/master/examples/ are examples of hard private. The position that https://github.com/erights/PNLSOWNSF/blob/master/examples/hiddenExample.js dominate the others is "not playing", but is not an anti-hard private position. I am not yet saying what my ranking is of the examples in that directory. But I do consider this not-playing position to be a reasonable perspective on how to support hard private. |
@erights, the particular question is not what is supported, but what is encouraged. There does not appear to be much disagreement on the question of whether hard private state for classes is currently encouraged (it is not); the debate is whether it ought to be. |
@bakkot @erights @zenparsing Rotate the question a bit and ask "Is hard private being discouraged by the current difficulty of staging and maintaining it?" I think the answer is a resounding "yes!" |
@littledan, ok, I understand your position. As I said already in emails, the outcome of |
@bakkot Yes, current proposal encourage hard private, but it also encourage many footguns (for example, encourage break Proxy by default). |
Originally I posted following messages in #149 answering to @erights concern about
Membrane
pattern implementation withSymbol.private
approach. I've decided to create new issue here for several reasons:#
-based syntax #149 (comment) and September meeting it seems to be a major concern againstSymbol.private
#
-based syntax #149, [Private] Metaprogramming vs Security #134 and [Private] yet another alternative to#
-based syntax #149 (comment)), and I'm not the only one who did it (e.g. What would it mean to drop branding? rdking/proposal-class-members#10), so IMO it could be solved ifSymbol.private
will reachstage 1
, so we'll be able to work on it or create follow-on proposals@ljharb, @erights, @littledan, @zenparsing could you, please answer to this:
Membrane
pattern a major concern?Membrane
+Symbol.private
issues with following solution?Symbol.private
(including my yet unpublished ideas)?Copied from #149 (comment)
@erights, as I said before there is a solution that makes your test reachable using
Symbol.private
, here's a sample:Copied from #149 (comment)
I skipped
fP->fT
andfT->fP
transformations in previous example for simplicity. But I'll mention such transformation here, since they are really easy handled when private symbols crosses boundary using public API ofmembraned
objectset on left side of membrane
set using left side field name
goes as usual, since happens on one (left) side of membrane
fP
is private symbol,get
called on proxy targetprivateHandler
objectprivateHandler[fP]
getter:fP
tofT
bT[fT]
which equalsvT
vT
tovP
vP
tovT
vT
tobt[fT]
as usualprivateHandler
)privateHandler[fP]
getter:fP
tofT
bT[fT]
which equalsvT
vT
tovP
vT
tovP
set using right side field name
fP
tofT
vT
tobt[fT]
as usualprivateHandler
)privateHandler[fP]
getter:fP
tofT
bT[fT]
which equalsvT
vT
tovP
fP
tofT
vP
tovT
vT
tobt[fT]
as usualfT
tofP
privateHandler
)privateHandler[fP]
getter:fP
tofT
bT[fT]
which equalsvT
vT
tovP
vT
tovP
set on right side of membrane
set using left side field name
fT
tofP
vT
tovP
vP
tobP[fP]
privateHandler
)privateHandler[fP]
setter:fP
tofT
vP
tovT
vT
tobt[fT]
as usualfP
tofT
bT[fT]
which equalsvT
vP
tovT
fT
tofP
vP
tobP[fP]
privateHandler
)privateHandler[fP]
setter:fP
tofT
vP
tovT
vT
tobt[fT]
as usualfP
tofT
bT[fT]
which equalsvT
set using right side field name
vT
tovP
vP
tobP[fP]
privateHandler
)privateHandler[fP]
setter:fP
tofT
vP
tovT
vT
tobt[fT]
as usualbT[fT]
which equalsvT
vP
tovT
vP
tobP[fP]
privateHandler
)privateHandler[fP]
setter:fP
tofT
vP
tovT
vT
tobt[fT]
as usualbT[fT]
which equalsvT
The text was updated successfully, but these errors were encountered: