New private names proposal
brendan at mozilla.com
Tue Dec 21 14:12:00 PST 2010
On Dec 20, 2010, at 11:05 PM, David-Sarah Hopwood wrote:
>> The new equivalence under private names would be x[#.id] === x.id.
> ... which is strictly weaker, more complex, and less explanatory.
So is a transposed get from an inherited soft field. Soft fields change the way square brackets work in JS, for Pete's sake!
Talk about more complex and less explanatory. Yes, if you know about weak maps and soft fields, then it follows -- that is a bit too circular, too much assuming the conclusion.
Either way (soft fields vs. private names), something changes from the old x["id"] / x.id equivalence.
> So, what if we want to
> understand '_._' in terms of existing constructs? Unfortunately,
> '#.id' must be primitive; there is nothing else that it can desugar
> to because 'private id' does not introduce an ordinary variable
> (unlike 'const id_ = SoftField()', say).
SoftField(), #.id -- something new in either case. And what's this "const id_"? A gensym?
It's tiresome to argue by special pleading that one extension or transformation (including generated symbols) is "more complex, and less explanatory", while another is less so, when the judgment is completely subjective. And the absolutism about how it's *always* better in every instance to use strong encapsulation is, well, absolutist (i.e., wrong).
We should debate strong vs. weak encapsulation, for sure, and in the other thread you started (thanks for that). But without absolutes based on preferences or judgment calls about trade-offs and economics. People differ on abstraction leak costs and make different trade-offs in programming all the time.
> Rather it introduces an
> element in an entirely new lexically scoped namespace alongside
> ordinary variables. This is fundamentally more complex than "id",
> which is just a stringification of the identifier.
I agree that "private x" adds complexity to the spec. It adds something to solve a use-case not satisfied by the existing language. There's (again) a trade-off, since with this new syntax, the use-cases for private names become more usably expressible.
> The fact that the proposal is entangled with that syntax, so that it is
> difficult to see its semantic consequences separate from the syntax,
> cannot possibly be considered a feature of the proposal, at the meta level
> of the language design process.
Didn't I already agree that it's a good idea to separate "private x" from the semantics, since we have a conflict over semantics?
So let's do that (my plea to everyone, not just you). Let's separate "private x" syntax, since I now know of a use-case courtesy Mark, and it's a good one (a frozen AST being extended sparsely via soft fields) that wants that "private x" and the sweet dot operator syntax, but on top of soft fields not private property names that require unfrozen objects.
>> The inherited soft fields approach is more entangled with its
>> reference implementation, which is not the efficient route VM
>> implementors can swallow.
> I think you're being rather patronising to VM implementors (including
> yourself!) if you think that they're incapable of understanding
I wrote "can swalow" not "can understand". "Swallow" and "understand" have pretty different connotations.
Mapping from soft fields to something more efficient that VM implementors will implement is non-trivial. Requiring all implementors (the primary audience of ECMA-262) to do this mapping, each on his or her own, is a bad idea. The spec should use formalisms that are not at odds with common implementation. But let's wait to hear from more implementors on this point.
In the mean time, how about we quit fencing over matters of taste or trade-offs turned into false absolutes, and try to get ahead on semantics: the issues that remain even after separating syntax are the abstraction leaks.
With inherited soft fields, the ability to "extend" frozen objects with private fields is an abstraction leak (and a feature, I agree).
With inherited soft fields, the transposed get or set magic that changes how square brackets work in JS is a leak on the inside of the abstraction. If you don't like x[#.id] / x.id supplanting x["id"] / x.id, it seems to me you have to count some similar demerits against this change.
With private names as proposed in full, the #.id syntax which can reflect a private name as an expression result, including the typeof-type or built-in class of a private name, is a definitely both new complexity that makes an overt observable difference between soft fields and private names. No such operator for soft fields.
The weak encapsulation design points are likewise "leaky" for private names, where no such leaks arise with soft fields: reflection and proxies can learn private names, they "leak" in the real ocap sense that secure subsets will have to plug.
To make progress, we could try to agree on strong encapsulation only. TC39 works by consensus, meaning general agreement, so we may not achieve consensus on strong encapsulation, but if we could, then I think almost all our semantic quarrels go away, since nothing other than frozen objects being "extensible" via soft fields, but not via private names, would be observable. Perhaps we could even agree that this was a feature of soft fields and be done.
If we somehow all agreed in committee (meaning, without you :-P) on strong encapsulation, then private names wouldn't reflect as values, period. I raise this even though it looks like it won't get consensus, to give it a fair and clear try.
If we can't get consensus in favor of only strong encapsulation, we might try for consensus in favor of weak encapsulation, with secure subset languages having a solid and demonstrated way to restore strong encapsulation at relatively low cost. But that would have to be solid and demonstrated.
I hope this helps. I'm not looking to debate to the death over all of private names vs. all of soft fields, since I'm pretty sure neither will have total victory. We do not want to end up with nothing, if there is a "something" we all could agree on that would materially help developers.
In this light, I'm still sympathetic to weak encapsulation. Mainstream languages do not lock all escape hatches: java.lang.reflect discloses private members, e.g. Languages that try to lock all escape hatches fail or breed extensions, often wildly unsafe. In particular, only closures in JS make leak-proof encapsulations and no one (I hope!) wants to change this (debuggers do not count).
I also see the ocap purity of soft fields, and I like Mark's AST-decorated-sparsely soft fields use-case. But we already have weak maps in harmony:proposals, so one can write such code now, just at some loss of convenience: without square brackets or (even better) dots for convenient soft-field access expressions.
This makes me think we want usable syntax for soft fields, as for anything like private property names. So to close, again I'd like to urge consensus building by splitting out the syntactic proposals where we can. Or even just mentally separating them for now.
More information about the es-discuss