-
Notifications
You must be signed in to change notification settings - Fork 19
Treat the #
as part of a .#
operator instead of as part of the variable name #foo
.
#113
Comments
So, then, we can have more dynamism and be closer to JavaScript origins: const privateProps = ['foo', 'bar', 'baz']
class Foo {
constructor() {
let i = 0
for (const privProp of privateProps) {
this[#privProp] = i
// or with any spacing this[ # privProp ] = i
i++
}
}
} With creativity, you can imagine use cases for this, like mapping a definition from an external helper (such as a decorator, mixin, or class factory) to private properties. |
Good luck with that. You're not going to get them to bite. I tried that suggestion (making |
@rdking Were there any particular problems that couldn't be solved? |
Oops, I posted in the wrong place anyway. I'll open an issue in the other repo. Private fields should not be merged to the other repo. in all honesty. |
Moved to tc39/proposal-class-fields#250 |
They already were merged, a long time ago. They will not be split. They are shipping at stage 3. # is part of the name and will forever be. This stuff has all been rehashed ad nauseum already. |
@ljharb Feisty! Q: Other than the |
@rdking The proposals were merged because we felt it was impossible to design one in the absence of the other. Having merged them once, the committee has very little appetite for splitting them again. Also, splitting them really would not affect anything. |
Let me see if I understand what I'm reading. You're saying it was impossible to add public fields to If, however, you're saying that private fields couldn't be designed without interfering with the design of public fields, then I have to call bologna again. The simple reality is that since the inception of WeakMap, private data has been being implemented completely without regard to public properties for some time now. So I have to say that I don't understand what the difficulty was. Is there any chance you can elucidate? There has to be something I'm not seeing. I'm sure others are curious as well. |
Yes, the syntax for private fields had to be designed at the same time as the syntax for public fields (ideally also the semantics, so they can form a cohesive mental model - which it is, even if you’re not a fan of it) |
I agree that the model between public and private fields is cohesive. What I do not understand is how that matters at all. ES has always had public properties. There's no 2 ways about that. There's also nothing particularly special about a "field" seeing as how it's just a deferred declaration of an instance property. The only things that needed to be decided to end up where we are with public fields are:
Those really are the only 2 considerations outside of the syntax. Everything else is already defined, including the mental model. From your perspective, question 1 answers itself since there is this uncannily strong desire to avoid the "instance object on the prototype" foot-gun. Question 2 has only 1 answer if the data is placed on the prototype: use Now, are you saying that if public fields had've gone to stage 4 without private fields, that it would have been impossible to design private fields to share a cohesive mental model with public fields? If that's not what you're saying, then I'm afraid I need to ask for a more detailed explanation of the problem. |
There were many other syntactic and semantic decisions which had to be made, and most of them were relevant to both proposals. If we had designed one with no consideration of the other, it is possible we'd've ended up with a design which the other could have been grafted onto with a minimum of fuss, but it is at least as likely we would not have. It did not make sense to design them separately. Again, this is mostly just a historical note about the process. The proposals are merged and are extremely unlikely to be unmerged, and unmerging them would accomplish nothing anyway because we have consensus on the entire design, including both public and private fields. |
@bakkot Don't worry. I've only been looking for the history. I'm long past expecting any result from arguing about both the process and results behind this proposal. Save for some unexpected event, I'm also way past hope for either halting this proposal, or at least correcting the rather grievous design flaws and technical trade-offs that force developers to give up on common design patterns or receive shocking results. (No slights intended. This is just how I feel about the technical merits of this proposal.) If I thought there was any chance at all, I'd want to see if I could at least change your perspective regarding the smallest of the technical problems (set vs define). But to even carry out that debate, I'd need to have a clear understanding of the intended goals and requirements. From what I understand, there's already a clear conflict of interest. However, I can't imagine that the TC39 members didn't already notice that when they made their decision. |
I'm not worried about the syntactic decisions. While it still think it could have easily gone in a better direction, I get how you ended up where you did. It's the semantic decisions that I'm interested in as they are breaking common paradigms. Thinking only of public fields, can you elaborate on what semantic decisions needed to be made that amounted to more than maintaining the existing nature of public instance properties? |
Sure: when do initializers run (both for base classes and for subclasses); in which scope are they evaluated; how do That said, the syntactic questions alone would have been sufficient reason to merge the proposals, once they were both stage 2. |
@bakkot Thank you again for being so forthcoming with these answers. Just as a matter of note, my answers would have been:
Up to this point, I don't even see these as questions since I would continue with the existing semantics. There really is no need to change how any of that works. Doing so would lead to unwanted and surprising results for common ES programming patterns. As for the rest:
Was this seriously a possibility? If this is how properties like If instead the internal slot can be created by the accessor's setter, then this is even better. However, it still falls apart if someone calls getOwnPropertyDefinition since they'll get back an accessor definition instead of the property definition they were expecting. So again, stick with existing property semantics. Short of flagging the accessor as a field somehow, it would prove difficult to fake the developer's expectations consistently, especially under edge cases. That was fun. Hopefully it also helped you understand where I'm coming from with what I've been saying. I get that there were many possible alternate paths that could have been taken and other questions you haven't listed. However, anything that deviates unnecessarily from the path ES has followed thus far regarding how a public property should behave should automatically be considered unacceptable. That's why I was able to reduce it down to just the 2 questions I listed. The answer to all others is "follow the existing pattern". |
The truth is, though public fields and private fields have similar syntax (what I called "duality"), the semantic of them are totally different (property-based vs weakmap-based). We already see many complains in the issue list because of that. To some degree, I agree public/private need to be designed together but unfortunately current design just fail on "form a cohesive mental model". |
I will not be surprised the proposal will cause more trouble to people once it releases |
@trusktr no, at the same time, since choices made for either private or public fields could impact the other, and that's not a risk worth taking imo. |
We've discussed the issue here thoroughly, and rehashed many of the reasons why we had previously concluded the syntax to be what it is. |
The following should work, and it would mean that we can provide much better functionality:
It didn't work in Chrome (I am doubting it is a bug in Chrome, and that is it working as spec'd, which throws a syntax error).
Looks like the
#foo
is treated as a name, which is what makes things like indexed-access not currently possible (or so it seems).If we change the semantics so that
.#
is an operator (f.e. it means "access a private property, of which the name follows"), and can be separated by spaces just like with public access using.
, then we can accommodate other features like indexed access in a way that makes sense:because now the syntax is tied to the type of access you want to attempt, not tied to the name of the field.
The text was updated successfully, but these errors were encountered: