Closed mbrowne closed 5 years ago
Set proxies to the side and leave them there. After spending time talking with @ljharb, the problem with Proxy is (imo) more due to insensible design than it any technical need. Making sure class-fields doesn't suffer due to the incomplete design of Proxy is likely as easy as it is to avoid for class-members. However, there are still other differences.... but I digress.
A normal closure, spec-wise is an execution context (basically a function, aka instance-closure definition). These things have a Lexical Environment. That's the real thing I'm calling an instance-closure and attaching to objects. Each Lexical Environment carries an Environment Record that has [[HasBinding]], [[GetBinding]], and [[SetMutableBinding]]. Since I'm attaching an Environment Record to the class instance during construction, the function of operator ::
takes care of peeking into siblings.
Functionally, this is all very similar to the WeakMap paradigm, but with very different consequences. First, since instance instance closures are created by executing a function and taking the resulting lexical environment, the initialization of an instance closure's variables automatically has access to the instance. Also this initialization is automatically specific to the instance. If I were re-convinced that it's not so distasteful, it would even be possible to treat the instance closure variables for the current instance as if they belong to the current lexical scope.
So while it can accomplish the same task, the method is very different. Instead of creating new structures and an unknown count of extra slots (1 for each private field), I'm using existing structures and 4 well-defined slots:
As for your example, yes. That works just fine. As for the spec, I'm still working on the runtime semantics, and haven't even started on the static semantics. It's my first time working on specs for ES. Learning the style and components available is taking a toll on how fast I can write it.
How it’s specified isn’t relevant to the observable semantics, and i don’t see any difference in those between the current proposal and yours, beyond surface syntax, set vs define (which has the same arguments with either proposal), and dynamism/reflectability (setting aside the Proxy topic).
How it’s specified isn’t relevant to the observable semantics...
Considering that the specification determines the observable semantics, that statement just isn't right at all. However, I get what you're trying to say. When I said,
Functionally, this is all very similar to the WeakMap paradigm
I had already conceded the similarities. My pointing out the spec details was to answer this question:
How can you implement private instance variables using a closure around the instance and still be able to access private variables of another instance?
It's because of those details than I can claim the paradigm is more similar to the closure approach than the WeakMap approach. That the same observable semantics can be achieved using a completely different approach is merely testament to the fact that the trade-offs of class-fields aren't necessary.
Given that the approach to specification is typically entirely divorced from what the semantics must be, and that the reasons for the decisions made in class fields have nothing to do with the approach to specifying it, I'm not sure what you mean.
I'll be more specific then.
No matter how you say "hello", it's a greeting. However, If by chance some audibly equivalent sounds are made with breaks in between, then it might not be a greeting any more. My point is that sure, multiple distinct specifications can produce the same result. This does seem to imply that how a semantic is specified is somewhat divorced from the semantic itself.
However, there exists specifications that won't produce the same semantic result. This means that the specification does indeed prescribe the semantics. The fact that there are multiple approaches to achieve the same result doesn't imply that the result is not affected by the approach. If it did, then a specification would be entirely useless for describing how language features should work.
I think this has been answered and seems to require no further action; closing this.
Looking at the spec for this proposal (admittedly I only read some of it), it appears that the following code would work:
Is that correct? While we could probably live without this feature (and academically speaking it's a violation of object encapsulation), I can see how it could be useful, and even very important when doing cross-realm brand checks.
And if this is indeed supported, then I'd like to follow up on your comment in https://github.com/tc39/proposal-class-fields/issues/163#issuecomment-437033774 to get a better understanding of how this works. How can you implement private instance variables using a closure around the instance and still be able to access private variables of another instance? And how is this any different from the "WeakMap paradigm", if it allows access across instances in the same way? Or is the way proxies are handled literally the only difference?