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

Developer experience of the syntax and semantics of this proposal #175

Open mbrowne opened 5 years ago

mbrowne commented 5 years ago

This new issue is intended as a continuation of the recent discussion in #100. (The only reason for a new thread is that the original has become very, very long, which among other things makes it less approachable to anyone not already participating in the discussion.)

VERY IMPORTANT NOTE: Anyone who would like to comment here should first read the PRIVATE SYNTAX FAQ. This will save everyone time. Thank you.

mbrowne commented 5 years ago

@hax In response to https://github.com/tc39/proposal-class-fields/issues/100#issuecomment-441167141...

The code examples are totally "syntax correct" as public field proposal.

Ok, I shouldn't have said "broken syntax". To be more precise, referring to other fields in an initializer without using this is incorrect usage of the syntax—it's based on a simple assumption due to unawareness of the need to use this. And by introducing this mistake as your first code sample, you would be encouraging such an assumption even among people who might not have made it in the first place.

But for the same reason, if you introduce public field motivation/syntax/semantic first, you also bias people's expectations

If you were to describe it all in depth then I would agree, but you have to provide at least some introduction (which I think should include using this in a field initializer) or it just becomes a guessing game that doesn't prove anything. One-sided portrayals of any kind should be avoided I agree with you about the risks of an "RTFM" attitude.

SCLeoX commented 5 years ago

As a sidenote, have anyone imagined what Java will be like without .setAccessible(true)? It will be mostly certain that many large framework or libraries that people rely on today will not be able to exist.

If that's the case, why are we trying to introduce hard private without a way to override?

Igmat commented 5 years ago

I’m told they have issues with membranes, and as such are not an option.

@ljharb do you still insist that they have issue with membrane even though I provided implementation of this pattern being aware of private symbols in https://github.com/tc39/proposal-class-fields/issues/149#issuecomment-441057730?

Igmat commented 5 years ago

I doubt that a majority of developers would find the tradeoffs of this proposal unacceptable...

@mbrowne I'm so active here for one reason: Breaking proxies - is nearly end of the world for me personally. One of my pet-projects utilizes proxies for providing fully-reactive properties (it's very close to what @observable decorator from MobX does) on object and classes without a need to explicitly put decorator to each field. While I realize, that JS isn't built and never will be built to fit only my needs, I'm pretty sure that such issue with Proxies and privates will lead to that some cool libraries/frameworks won't be ever created. Average developer won't notice that, but will suffer from lack of some very useful tools.

I don't think informal surveys tend to produce deeply considered and unbiased responses.

Any kind of survey backed with article that presents item to discuss (even if it does it in biased manner) is better than just subjective opinion, even if this opinion belongs to such intelligent people as members of tc39 committee.

P.S.

BTW, I frequently hear that my article is biased. But it doesn't seem that anybody is able prove that, because I didn't put my opinion into this article (in case if I did that, poll should reflect my personal preference to have this proposal rejected in favor of Symbol.private but it doesn't) - I just listed its disadvantages and problems. Can you tell that this proposal doesn't have this listed issues? Or probably it provides viable workarounds for them? Or solutions for them lead to something even worse? Or impartial way for presentation of this proposal means avoiding to talk about its downsides?

slikts commented 5 years ago

Neutrality is when the opinion of the author can't be determined from the writing; ideal neutrality is usually not possible, but your article doesn't even have a pretense of neutrality; it starts out by spelling out what you think of things even in the title and then stays editorial.

mbrowne commented 5 years ago

I agree with @slikts on this point...I don't doubt that you held back in expressing some of your opinions, but the article is far from impartial. It was still good to get another measure of community feedback, but it has to be considered in context.

Igmat commented 5 years ago

@mbrowne, @slikts how does article that describes BOTH pros and cons of this proposal should look like? I tried to create such, and you see the result. It may look like not impartial, but this happens only because list of issues of this proposal objectively outweighs its advantages. EVERY issue in that list has mentions of positive aspects of current proposal. How do you propose to create more neutral article for this proposal that includes BOTH pros and cons? Have you ever tried to do it?


UPDATE:

objectively outweighs its advantages.

at least until committee provide us with properly justified list of priorities and assumptions backing existing this proposal.

slikts commented 5 years ago

A neutral approach would be providing some criterion of relevance and listing facts matching that criterion and leaving the value judgement or interpretation to the reader. You can't in good faith claim that that's what you've done.

SCLeoX commented 5 years ago

As long as the article's content is correct and the author did not intentionally leave out information, the readers should be able to make their own decisions. It is not fair to ask authors to write completely neutral articles while the readme of this repo only covers the advantages of the proposal without any indication of potential weaknesses.

Igmat commented 5 years ago

Quotes with my own opinion from that article:

Despite all of the above, I am not an irreconcilable opponent of the[[Define]] semantics (although I would prefer [[Set]]), because it has its own positive aspects. However, unfortunately, its advantages do not outweigh the main disadvantage - we have been using [[Set]] semantic for years, since it's used in babel6 and TypeScript by default.

While encapsulation is required for almost all types of code, brand-check has very limited number of use cases. Mixing them into one syntax will lead to appearing of dozens of unintended brand-checks, when developer just wanted to hide implementation details.

And In lieu of conclusion part of the article.

Everything else is facts without judgement and interpretation, just facts. @slikts (or @mbrowne) are you able to prove the opposite? If yes, please go ahead and create your article (or just a comment here in github), which shows logic flaws or false facts in my review. If not, you have to confess that my article is more neutral than FAQ, README and presentation made by committee till this moment, because it doesn't hide issues under the carpet.

Igmat commented 5 years ago

I don't want to blame or offend anybody, but I think that supporters of existing proposal see my article as not impartial, because while reading they feel proposal becoming not as good as they felt it before. And the easiest explanation is that author isn't neutral and not that biased reader had wrong assumptions or missed something important during initial evaluation of current proposal.

slikts commented 5 years ago

This just isn't serious. The article is blatantly not neutral; it gives your preferred interpretation even in the title. There can't be a discussion if the basic facts can't be agreed upon. The relevance of neutrality is that it's a starting precondition for reliable polling, but just starting; beyond that there's complex questions like how to control for self-selection bias, etc. Bringing up the FAQ and readme is just deflection.

I don't want to blame or offend anybody, …

Having to include a disclaimer like this should have been taken as a clue that it's not appropriate.

mbrowne commented 5 years ago

@Igmat I agree that the readme of this repo is not neutral, but I don't think it has any obligation to be. Do you think every TC39 proposal should be required to include a long list of downsides and potential downsides in its readme rather than simply stating the purpose of the proposal and making a case for it? As to the documentation in this repo in general (not just the readme), could it be improved by better documenting tradeoffs and drawbacks of the proposal? Certainly. But again, I don't think it has an actual obligation to do so. If the community were to put together a list of tradeoffs that fairly covered both sides of the argument and posted it somewhere, then it would be reasonable to request that there be a link to it in the readme, but that's about it. Expecting a full documentation of not only the pros but also the cons of the proposal is simply asking too much of the committee, and the community already has plenty of opportunity to bring up problems and concerns in these discussion threads.

And finally, just because the documentation of this repo isn't as impartial as it could be doesn't mean that when conducting a survey you should focus more on the counterargument. Regardless of whether the documentation here were neutral or completely biased, the correct way to do research is to just stick to the facts and/or present both sides as neutrally as possible.

Igmat commented 5 years ago

@slikts, @mbrowne remove three paragraphs I mention before as my own opinion and add actual possibility to declare public and private fields for classes line to the begining and you'll get a list of tradeoffs that fairly covered both sides of the argument, becasue everything else in my topic ARE FACTS.

But I'm not trying to convince anybody that my research is 100% correct, even though I doubt that such change to the article will significantly affect survey results.

BTW, you are welcomed to make your own survey - I'll provide you with my text in .md format if needed and you may change it in any way you think appropriate and publish it anywhere even without a link to me or my article.

I just fulfilled the gap in argumentation of opponents of existing proposal.

So what do we have now?

Argument Committee Opponents
Technical - +
Feedback - +
Readiness + -
robbiespeed commented 5 years ago

The community feedback of the proposal continues to show # sigil to be undesired. There is a lot of concerned feedback both in the issues of this repo, and whenever it get's mentioned in community forums see this latest post on reddit about babel support. What worries me the most is the only defence being brought forward, is that the sigil is the only proposal that allows for hard private. We know that not to be the case, there have been suggested alternatives with near identical feature parity even.

I fail to see why Private Symbols are not adopted in place of the sigil syntax, for 3 main reasons:

To show what I mean by greater flexibility, something that is not possible with the sigil syntax.

const sizeHandlerSym = Symbol.private();

Array.prototype[sizeHandlerSym] = function () {
  return this.length;
};

Set.prototype[sizeHandlerSym] = Map.prototype[sizeHandlerSym] = function () {
  return this.size;
};

function getSize (collection) {
  return collection[sizeHandlerSym]();
}

class Foo extends Map { ... }

getSize(new Foo());

@mbrowne I agree that the readme of this repo is not neutral, but I don't think it has any obligation to be. Do you think every TC39 proposal should be required to include a long list of downsides and potential downsides in its readme rather than simply stating the purpose of the proposal and making a case for it?

Yes, I think they should be required to include drawbacks, and/or alternatives sections. Many RFC processes already do this. It seems like the FAQ attempts to cover this, but ends up being one sided, by only selectively showing alternatives that fail. IMO this is even worse, because it falsely props up the proposal.

littledan commented 5 years ago

I agree that we should have an open discussion about pros and cons of proposals, and would appreciate your help in collecting this in general. For future proposals, let's try to collect this input earlier in the process, prior to Stage 3, so that it's easiest for TC39 to take it into account. At some point, though, a conclusion should be drawn, and a rationale published.

mbrowne commented 5 years ago

@littledan Does this mean that the committee is working on a rationale document explaining the decisions that were made on this proposal? I think we have some sense of individual arguments in favor of certain points, e.g. hard privacy and the syntax, but what's missing is the big picture, particularly why this proposal was chosen instead of alternatives, for example:

(I can imagine a rationale document that would make a strong case for the current proposal over these alternatives. It wouldn't satisfy everyone of course, but I think it would help explain the decisions in a way that the meeting notes currently don't do adequately.)

littledan commented 5 years ago

I meant, we should make such comparison/rationale documents earlier in the process of future proposals. For proposals at later stages of development, like this one, an FAQ explaining the selected option is probably the more relevant thing.

If anyone wants to write either form of documentation for this proposal, I would be happy to review it and include it in this repository.

Right now, I'm most excited about @neilkakkar 's effort to document this proposal in MDN, and other efforts to help JavaScript developers use the feature, rather than explain the rationale.

mbrowne commented 5 years ago

For proposals at later stages of development, like this one, an FAQ explaining the selected option is probably the more relevant thing.

Ok, it could be in an FAQ format; the important thing is "explaining the selected option". But I don't see how a non-committee member could write the first draft...plenty of details can be gleaned from public statements by committee members, but the big picture...? (For the syntax, the private fields FAQ would be an excellent starting point, but the syntax is only one aspect.) Maybe a gist from the committee with some bullet points could provide the starting point, and community members who are familiar with the issues (hard vs soft privacy, Set vs Define, etc.) could fill in the details including a glossary of terms.

Right now, I'm most excited about @neilkakkar 's effort to document this proposal in MDN, and other efforts to help JavaScript developers use the feature, rather than explain the rationale.

Given that the committee has already reached consensus on this proposal, it does make sense for this to be the first priority, yes.

littledan commented 5 years ago

You're right, it doesn't need to be in FAQ form. Happy to answer any questions you have; I would recommend starting with the past presentations and notes linked from the readme if you are interested in history beyond the rationale we have been discussing in these threads.

neilkakkar commented 5 years ago

Yes, it's a good idea to ask questions. If I know about FAQs beforehand, I can pre-emptively include them in the documentation.

mbrowne commented 5 years ago

I thought @littledan's most recent comment was in reference to the rationale for choosing this proposal over alternatives. As to usage, personally I'm pretty clear on it. But I do have an idea for a usage FAQ question...

Question: How do I access fields defined in a subclass from a parent class's constructor? Answer: This is intentionally not possible. [Then explain how internally, fields aren't defined until after calling super.]

littledan commented 5 years ago

Happy to discuss both kinds of questions.

mbrowne commented 5 years ago

Thank you @littledan! :) I started a new thread for this: https://github.com/tc39/proposal-class-fields/issues/178

MichaelTheriot commented 5 years ago

Catching up on this long thread. Were non-React use cases for public fields ever posted? They still seem redundant to me if you are defining a constructor, and if you are not defining a constructor then using a class over a plain object seems unusual. Would like to understand more.

littledan commented 5 years ago

@MichaelTheriot Yes, for example, see the example in the explainer of this repository, which is based on custom elements and does not use React.

MichaelTheriot commented 5 years ago

If we are talking about the same example it appears to suffer from the same issues I mentioned.

mbrowne commented 5 years ago

@MichaelTheriot for a recent, detailed discussion of this issue, see https://github.com/rdking/proposal-class-members/issues/1 and the continuation of that discussion in https://github.com/rdking/proposal-class-members/issues/3

mbrowne commented 5 years ago

Also https://github.com/tc39/proposal-class-fields/issues/142#issuecomment-440877037, and https://github.com/tc39/proposal-class-fields/issues/100#issuecomment-439619952

ljharb commented 5 years ago

If you’re not defining a constructor but are inheriting from another class - one that has an API that reads from instance properties - then you couldn’t use a plain object (or instanceof would break).

React is just one example of this pattern; Backbone is another, and I’m sure there’s many current ones too that i don’t have available off the top of my head.

trusktr commented 5 years ago

Sidenote, as an end user of "open standard" JS and Web APIs, I feel that our developer experience may not always valued enough. The discontent summarized in #100 is another example.

rdking commented 5 years ago

@ljharb

If you’re not defining a constructor but are inheriting from another class - one that has an API that reads from instance properties - then you couldn’t use a plain object (or instanceof would break).

Not true, since that plain object can just do:

let myobj = {
  somefields: somevalue,
  __proto__: ExpectedClass.prototype
};

This is still a fundamentally prototype-based language.

ljharb commented 5 years ago

@rdking you’re correct of course, but “plain object” tends to mean one that inherits directly from Object.prototype; you’re describing an object literal.

rdking commented 5 years ago

Fair enough. I was thinking of "plain object" in terms of an object not created by any kind of factory function or class.

Mouvedia commented 5 years ago

It would be unexpected and weird if "private" things were publicly visible properties that threw on access, exposing their existence.

Assuming that private properties are not enumerable, if non-public—even non existing ones—properties throw, it virtually seals the class—i.e. preventing any additions. Is not allowing additions (which would allow private properties detections) be such a big concession? That way you won't be able to tell if a private property exists by trying to access it.

ljharb commented 5 years ago

Yes, it would be an unacceptable concession; JS objects are extensible by default, and making "adding the first private field" be the equivalent of adding Object.preventExtensions(this) at the end of the constructor, or making "removing the last private field" the equivalent of making the object suddenly and surprisingly extensible, would be a very confusing situation for the language to find itself in.

Mouvedia commented 5 years ago

@ljharb of course that would be accompanied with a way to reflect that state (a property boolean or predicate function).