proposal-class-fields icon indicating copy to clipboard operation
proposal-class-fields copied to clipboard

Treating the `#` as part of a `.#` operator instead of as part of a field name `#foo`.

Open trusktr opened this issue 6 years ago • 39 comments

The following should work, and it would mean that we can provide much better functionality:

class Foo {
  #      x = 5

  test() {
    console.log(this  .#      x) // it should work, but it doesn't
  }
}

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:

const propName = 'bar'

class Foo {
  foo = 3
  # foo = 4
  [# propName ] = 5

  test() {
    console.log(this  .      foo) // it works, 3
    console.log(this  .#      foo) // it should work, 4
    console.log(this[#'foo']) // it should work, 4
    console.log(this   [#   'foo' ]) // it should work, 4
    console.log(this  .#      bar) // it should work, 5
    console.log(this [#    propName ]) // it should work, 5
  }
}

because now the syntax is tied to the type of access you want to attempt, not tied to the name of the field.

trusktr avatar Jun 26 '19 18:06 trusktr

Then we can have 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.

trusktr avatar Jun 26 '19 19:06 trusktr

I disagree that it should work. # is part of the name, and this is an important part of the mental model.

Separately, i don’t agree dynamism makes sense for this feature, given that you can store any kind of object or collection you want in a private field if you need to iterate.

ljharb avatar Jun 26 '19 19:06 ljharb

I suppose by "mental model" you are referring to the very proposal of this github repo, which many people don't like.

You know, you (tc39 in general) can change the proposal (and the mental model) to something that people like more.

trusktr avatar Jun 26 '19 19:06 trusktr

Honestly speaking, in this.#foo, the name does not intuitively seem to be #foo.

Valid JavaScript identifiers have never had # symbols. I wouldn't suddenly think #foo to be valid. Try it yourself here: https://mothereff.in/js-variables

This makes no sense with respect to this['#foo'], obviously.

The mental model is gross.

trusktr avatar Jun 26 '19 19:06 trusktr

“what people like” is important but certainly not the reigning concern. There is nothing people like more that meets all the constraints of the committee, which is why this proposal as-is is what’s shipping in browsers.

ljharb avatar Jun 26 '19 19:06 ljharb

Note that, in case TC39 change their mind and decides that dynamic access is a necessary feature, the syntax of this proposal doesn't prevent a possible future this[# "foo"] syntax.

nicolo-ribaudo avatar Jun 26 '19 20:06 nicolo-ribaudo

That seems to be wrong. According to @DanielRosenwasser in https://github.com/tc39/proposal-class-fields/issues/248#issuecomment-502970350,

My feeling from speaking with a decent number of members of the committee is that many people are saying "Set was actually the right one, but I think it's probably too late."

So, there are things people like more. Some constraints should be modified.

Note that, in case TC39 change their mind and decides that dynamic access is a necessary feature, the syntax of this proposal doesn't prevent a possible future this[# "foo"] syntax.

Then, in that case it is important to shift the mental model so that .# is an operator, and foo is a name. And thus we may as well allow spacing.

It's not a huge change. I don't think it affect the currently functionality.

trusktr avatar Jun 26 '19 20:06 trusktr

If we could roll back a much more useful feature such as Object.observe, we can certainly roll back private fields (and change public and static ones to [[Set]]).

trusktr avatar Jun 26 '19 20:06 trusktr

That was stage 2. This is stage 3. It’s not being rolled back.

ljharb avatar Jun 26 '19 20:06 ljharb

Remember, private fields was unfairly rushed from stage 2 to stage 3 in just two months. It shows a lack of respect towards end users (with regards to this feature) on behalf of TC39.

trusktr avatar Jun 26 '19 20:06 trusktr

There’s nothing “unfair” about that; there is no proscribed minimum or maximum for a proposal to be at any stage.

ljharb avatar Jun 26 '19 20:06 ljharb

Of course, a person burglarizing a home doesn't think what they do is unfair. I'm the end user (the person whose home is burglarized).

trusktr avatar Jun 26 '19 20:06 trusktr

@ljharb Perhaps there should be. A number of people feel this was rushed.

jhpratt avatar Jun 26 '19 20:06 jhpratt

Petty arguments (both sides) aren't really productive.

The committee has been discussing private fields for 6 years. This is the first design that has managed to gain real traction. Going back to stage 2 isn't going to produce a better design, it's just going to stagnate it more.

jridgewell avatar Jun 26 '19 20:06 jridgewell

This is the first design that has managed to gain real traction

In what sense? Traction with limited committee members? Traction with the community? How do you explain traction with more downvotes than upvotes?

trusktr avatar Jun 26 '19 21:06 trusktr

it's just going to stagnate it more.

Then maybe we should let it die. ;-P

hax avatar Jul 01 '19 15:07 hax

@jridgewell Has TC39 considered the possibility that the collection of demands being pushed by the various board members may have lead to this controversial design, and maybe it's these demands that need to be checked before anything less controversial can be constructed?

rdking avatar Jul 01 '19 15:07 rdking

The collection of delegate criteria and constraints is what leads to every design, so I’m sure we’ve considered that ~possibility~certainty.

Short of persuading delegates to change their positions, I’m not sure what “checking” you’re looking for. Nobody’s constraints will be steamrolled; that’s the value of the consensus process.

ljharb avatar Jul 01 '19 15:07 ljharb

@ljharb

I’m not sure what “checking” you’re looking for.

Put simply, I like playing best when all the cards are on the table. Design by committee is almost as hazardous as community driven design for this very reason. My opinion is that the first step should be to gather all of the concerns into a formalized list of requirements (I believe I've said this before). Then the requirements need to be reviewed for conflicts of interest and other such inconsistency-causing issues. This is the "checking" to which I'm referring. When this is done, you can at least be certain that what you're building won't be trying to perform and not perform at the same time.

rdking avatar Jul 01 '19 15:07 rdking

and what happens if such an inconsistency exists but we’re all still comfortable progressing with it?

ljharb avatar Jul 01 '19 15:07 ljharb

In the interest of fairness, I don't think you really want me to answer that.

rdking avatar Jul 01 '19 15:07 rdking

I think I thought of a non-volatile way to explain my answer. Suppose someone (the contractee) hired a committee to build the best possible house for that person's use. The committee is responsible for learning about that person and how they live, daily habits, etc... and building a house that best suits that person. The committee discusses a set of somewhat conflicting requirements without ever including the contractee in any meaningful way until a blueprint is made and almost fully complete.

Upon seeing the blueprint, the contractee raises several usability issues with the house's design and suggests multiple means of correcting these issues. However, the comittee insists that they've done their due diligence and have discussed all such alternatives. They have come to the consensus that the house design they've created is the best that they could create for this contractee.

Do you think the contractee will accept the house design, even if it includes so many good things if it also comes with encumbrances and inconsistencies that will force the contractee to change his/her lifestyle? If it's not possible for this analogy to be understood as is, then there is no gentil means for me to answer you, and my previous statement will have to stand.

rdking avatar Jul 01 '19 16:07 rdking

I understand your analogy, but “contract” doesn’t describe the relationship between the community and the committee.

ljharb avatar Jul 01 '19 17:07 ljharb

@rdking This analogy is entertaining to me because if you talk to people who design houses about what happens when the people who hire them get involved in the process, what they describe is that those people inevitably suggest things like "why don't you build this load-bearing wall out of glass" and get frustrated when the answer is "we are not going to do that; the house will fall down".

To be slightly less facetious:

the contractee raises several usability issues with the house's design and suggests multiple means of correcting these issues. However, the comittee insists that they've done their due diligence and have discussed all such alternatives.

We've discussed all the alternatives in public. When people have suggested alternatives, we've explained why we think those aren't good choices. I've explained elsewhere why I don't think it makes sense to think of this as a problem for which all constraints can be enumerated up front, so I think this iterative back-and forth, where people suggest things and other people discuss their problems with those suggestions (and which I have been engaging in with you and others here for several years) is the best which can be done.

bakkot avatar Jul 01 '19 17:07 bakkot

This committee has too much power to control the future of the web as a platform. Especially if this is how they see those that are passionate and knowledgeable enough to spend this amount of time and effort to object to and discuss such low level issues with this proposal. They come with technical details and valid arguments. Not derpy comments and frivolous suggestions.

shannon avatar Jul 01 '19 17:07 shannon

@bakkot Where appropriate, be facetious more often. That was funny. True, people can suggest stupid things. However, what if the design called for 2.5 feet wide doorways and the contractee complained saying the doorways needed to be at least 3 feet wide, then the contractor still replies "no, we're not going to do that because we thing 2.5 feet wide doorways are better". Aligns a bit with what's going on here, doesn't it?

rdking avatar Jul 01 '19 18:07 rdking

By the way, I never asked for all constraints to be enumerated up front. It's natural that some of them will not be discovered until later. However, I did ask for them to be enumerated, which by now, 1st & Goal at the 1 yard line, could've and should've been done by now.

rdking avatar Jul 01 '19 18:07 rdking

@rdking Where the analogy breaks down is that we are designing a thing to be used by millions of people, many of whom have not yet been born, rather a single contractee. (And many of whom will have different use cases and expectations and consequently disagree with each other.) At some point, we have to say "in our best judgement, based on our experience using and designing programming languages, and despite the fact that some people have expressed a contrary preference, this seems like the design which is most likely to lead to people confidently and correctly reading and writing JavaScript which solves their problems". People will disagree about which design is best. People within the committee, even, and we ultimately have to pick one (including "do nothing" as an option, of course). But we are all trying to make that judgement.

The FAQ enumerates many of the most commonly encountered constraints from this repo, and has done for quite some time. But fundamentally, since very few of them are about what is technically feasible rather than what is a good design, they will usually ultimately boil down to the above judgement call.

bakkot avatar Jul 01 '19 20:07 bakkot

@bakkot I understand your (TC39's) perspective, and believe it or not, I do respect it. However, I also believe that you have either ignored, overlooked, or failed to comprehend something important. Those many contractees who have yet to be born will mostly be indoctrinated into the language by those of us who are already here and already using the language.

The problem we're having isn't one of our(the ES community's) opinion vs your (TC39's) opinion, but rather our coding practices, standards, and conventions developed over the lifetime of the language vs your opinion. Your opinion is basically asking us to throw away tried and true, battle-tested paradigms, patterns, and practices just to gain a new feature or 2 that by it own nature doesn't have (and isn't supposed to have according to you) anything to do with those paradigms, patterns, and practices.

You in TC39 aren't the only one in the ES community who have experience with the language, and with designing languages. Compound this with the fact that despite the consensus, there are still those among you who would rather the choices have been different for reason that agree with us in the community, and it should be perfectly reasonable that there will be push-back. Just because there's always air surrounding your body doesn't mean its a good idea to ignore breathing. Likewise, just because human beings in a group of nearly any size > 3 have a hard time agreeing to anything doesn't mean that the arguments that get raised as a result should be so easily dismissed because a subgroup of < 1% in influential positions say this is "our best judgement".

Look. It's too late for class-fields. Not because of anything specific to the language or any technical details, but rather because you say so. You give us no recourse, no vote. So how about this. Currently the makeup of TC39 is a collection of delegates from various companies who could buy their way in. Who or where is the delegate that represents the community, unencumbered by corporate pressures? If there isn't one, get one. Make that one take on the role of gathering the community's perspective and voting accordingly. Or, if you don't think a human can manage that role appropriately, use a website to perform the same task. In either case, take the community as a whole as a single seat at the table, complete with the power to block proposals.

rdking avatar Jul 01 '19 23:07 rdking

The JS Foundation is a member and sends delegates for exactly that purpose. They were part of this consensus too.

ljharb avatar Jul 02 '19 01:07 ljharb