tc39 / proposal-class-fields

Orthogonally-informed combination of public and private fields proposals
https://arai-a.github.io/ecma262-compare/?pr=1668
1.72k stars 113 forks source link

What's missing #212

Closed trusktr closed 5 years ago

trusktr commented 5 years ago

Maybe people will learn to accept #-based syntax.

More important is the functionality. It'd be great if the spec (namely the README here) could describe how some features can be added later. For example it could have a section along the lines of:

Features for later (in add-on proposals)

  • interop with existing JS ecosystem
    • string-based access for private members (f.e. this[#'someProp'])
    • _.pick(this, 'x', 'y', #) or something.
  • prototype-based private members. Re-use methods across instances so not to waste memory.
  • descriptors, f.e. Object.defineProperty(this#, 'x', {...}) or Object.defineProperty(this, 'x', {...}, #) or something.

My example is simple, and perhaps has issues, but you can gather what functionality I'm listing. I've listed more features here: https://github.com/tc39/proposal-class-fields/issues/206#issuecomment-452966767.

Can some effort be put forth by spec champions on how to tackle these problems later, and leave room for such future features in the spec?

bmeck commented 5 years ago

I think follow on features should be proposed separately. There are mentions about all sorts of possibilities through both issue threads and there are parts of the FAQ that would place the features above as being separate from the goals of encapsulation that this proposal is aiming for. We should not tie this proposal to follow ons unless we have design issues with the existing semantics. If you have concrete issues with the semantics, we can discuss them, but without proposals that are blocked by some part of this proposal it seems a separate concern from this proposal.

littledan commented 5 years ago

Closing re https://github.com/tc39/proposal-class-fields/issues/212#issuecomment-453639818

trusktr commented 5 years ago

@bmeck @littledan f.e. Does super work with class fields? If not, how can it work later if it is designed only to [[Define]] onto this? That's a big problem because class is about inheritance and class fields don't seem to be.

ljharb commented 5 years ago

class is not only about inheritance; if it were, an extends would be required.

littledan commented 5 years ago

super.method() calls work inside of field initializers, if the class is a subclass.

trusktr commented 5 years ago

class is not only about inheritance; if it were, an extends would be required.

Nope, because a base class extends Object by default.

ljharb commented 5 years ago

@trusktr super() doesn't work in a base class.

rdking commented 5 years ago

@trusktr Does a base class extend Object? Well, yes and no. Like every other object, Object.prototype is used as the default prototype of the prototype object for the newly declared class. That's the "yes".

The "no" is a bit more complicated:

  1. The internal property for the "extends" element of the class is set to null, not Object.
  2. The prototype of the constructor function is Function, not Object.

Because of 1, it is not possible to use super(), as @ljharb said. I was told they did this to make constructor functions of base classes compatible with ES5-style factory functions. Requiring super() when the returned object wouldn't be this makes little sense. They could have chosen differently, but oh well.

trusktr commented 5 years ago

super() doesn't work in a base class.

@ljharb Yes it does, if you want it to.

class Bar extends Object {
  constructor() {
    super()
    this.x = 5
  }
  toString() {
    return super.toString()
  }
}

const b = new Bar
b.toString() // it works

That's a perfectly fine example of a base class, and yes, the semantics are different in base classes where inheritance is automatic if you don't specify the extends part.

Simply put, inheritance is always at play. Anything with prototypes is about inheritance. Classes are about inheritance. Otherwise, you don't need classes and can stop using them.

Please, think of this when you're designing class features, for the better.

ljharb commented 5 years ago

@trusktr no, a base class is defined as one that lacks an extends clause. That’s not a base class. As for inheriting from object, functions and arrays and regreses inherit from object too, but none of those are “all about inheritance”, so in fact “inheriting from object” is irrelevant.

trusktr commented 5 years ago

@ljharb I already knew you were going to reply with a textbook spec answer.

Yes, the textbook definition of "base class", in that sense, is exactly a class without extends. But in a non-textbook sense, the class I showed you can also and obviously be a base class too.

And in both cases, inheritance is happening in one form or another.

In practice, I do write the textbook-sense of base classes from time to time, but the majority of the time I'm using extends when I write a class. [[Define]] works well in textbook base classes, but not necessarily in non-base classes.

You're don't seem to be thinking like an end user for the purposes of defining this spec, it seems you specifically choose not to think from that perspective, because you cancel out those opinions based on textbook requirements. (no offense intended, it just seems to be what you are doing).

The community wants something, but you can't accept what they want because they don't necessarily stick to the textbook ideas (based on your textbook remarks).

My recommendation would be to implement your own privacy system (or have you already?), use it for a while, get actual experience with it, then come back to see if your opinions still hold.

ljharb commented 5 years ago

You're obviously not as much of an end-user of the language as I am,

If you want to get continued engagement from people, you may want to avoid being hostile. I'm not "obviously" anything, and I don't think it's productive to try to make fallacious arguments based on some alleged metric of "how much of an end user" you think someone is.

It's a base class when you don't explicitly extend anything else, conceptually. That's why the spec definition matches that concept, not the other way around. That something implicitly inherits from Object has no relevance - class extends null { } is still using inheritance, and is still not a base class.

Either way, I don't think continuing this discussion with you is productive at this point, so I'm going to withdraw.

trusktr commented 5 years ago

Why don't you make some polls and present them to communities on Twitter, Reddit, and other places, and see what people actually want? Someone needs to do that work, and who better else than spec authors from TC39?

trusktr commented 5 years ago

@ljharb Can you imagine how awesome new features (and the future of the language) would be if they had hundreds of upvotes instead of hundreds of downvotes? It seems like you and the other spec authors don't care about that. You all say you do, but do you really?

trusktr commented 5 years ago

and I don't think it's productive to try to make fallacious arguments based on some alleged metric of "how much of an end user" you think someone is.

I didn't mean to be hostile, so I re-worded that, but not soon enough before you saw it.

However, this is a fact: you tell me that my example is not a base class. As an end user, I say that it is. The language, is for the end users of the language. Those end users and very clearly articulating that they aren't satisfied with the outcome here.

And when someone voices an opinion, you manage to come up with a textbook remark saying why that opinion is invalid and thus make it feel as if the opinion must not be taken into consideration.

Please consider end users more than you do (or make it more obvious) by avoiding turning down opinions with textbook answers. That's what I meant.

It's hard not to feel this way that I do (because of the above), and unfortunately it seems I'm one of the fewer people that care to spend time mentioning it.

Also unfortunately, most developers I know would never spend the time to write anything here let alone post a bug report in any of the libraries they use unless it is of immediate business value, and are the sorts of people that will take the private member feature that you toss at them and use it within it's limitations with a shrug, and carry on with the next project.

A good goal to have would be to turn people's minds around and make them praise JavaScript rather than them just using it for business needs, by making extraordinary advances to the language without prematurely releasing new features (like I feel is the case here with class fields, especially the private kind). class is an example of a great change, but class fields not as much IMO.