Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Consider re-separating Class proposals #81

Closed
justsml opened this issue Feb 5, 2018 · 21 comments
Closed

Consider re-separating Class proposals #81

justsml opened this issue Feb 5, 2018 · 21 comments

Comments

@justsml
Copy link

justsml commented Feb 5, 2018

Some background: I'm originally a hardcore C++/C#/Java fanboi. In 20 years since I've come to appreciate many very different languages/styles/patterns: x86 Assembly, OCaml, Python, SmallTalk, Ruby, JavaScript, Elm, Elixir, ReasonML. I'M NOT A class HATER.

Here's my concern: If features keep getting added that are mostly tied to the class construct, we move far away from "classes are just syntactic sugar for functions + prototypal inheritance"

I understand the included transpilers show this is technically still true.

The new proposed features+syntax ratchet up the complexity considerably.

Think for a minute that Original ES2015 Classes could be 90% 'transpiled' using only a few regex replaces.

We have deviated so far from this 'simplicity' - there are so many new things in classes that all interact in different & exponentially more complex ways. decorators, getters/setters, static, field declarations, private members, et al.

Now consider how inheritance plays w/ all this, what about the existing expectations around Object.keys, Object.getOwnPropertyNames, etc? Can I use all the new syntax in the context of a plain JS object/function?

Btw, I know this proposal doesn't tackle all the features I listed, it's more about the cumulative effect of yet more class features.


Bottom line, if you want these sort of features added to JavaScript, just stop. Use TypeScript instead. It's world-view is much more inline w/ the proposed features.

If nothing else, I'd love to see the class proposals re-broken up.
It feels like TC39 is switching to a Waterfall/Log-roll style process to shove the lot of class proposals together into the spec.

Granular features allow for more careful consideration, and more helpful/specific community feedback.


Kudos to all the super smart people behind these proposals, it's an amazing amount of work, I do appreciate trying to advance JS. 😻

@ljharb
Copy link
Member

ljharb commented Feb 5, 2018

It’s fine to move far away from that; the goal of class isn’t to be simple sugar.

TypeScript does not have hard privacy; JavaScript will. This is absolutely critical - so even if “use typescript instead” was a productive or universally desirable recommendation, it wouldn’t be sufficient to replace the current proposal for private instance fields.

@justsml
Copy link
Author

justsml commented Feb 5, 2018

Thx @ljharb

I want simple sugar, the kind my brain can transpile w/o too much damage.

Btw, I've read up on the FAQs/prior issues, #77 (comment)
et al.

I feel the departure from simple sugar is turning JS into TypeScript... Just because it's not real in TypeScript doesn't mean JS must transform into TypeScript.
We've made it this far w/o these features, is it really worth the cost in complexity?

It seems most demand is from API devs unhappy ppl used their code in unexpected ways.

@ljharb
Copy link
Member

ljharb commented Feb 5, 2018

Yes, it's really worth the cost. Note that nobody is forcing you to use any of the newer language features; you can write ES3 forever if you prefer.

(Separately, your original claim is wrong: due to super and new.target and extends-on-builtins, class can not be transpiled fully at all, let alone simply)

@littledan
Copy link
Member

This proposal adds features which are difficult to implement in JavaScript today. That makes the feature more valuable, not less. TC39 has discussed "transpilability" as a goal, and although it can be a nice thing to have sometimes, it's not a general requirement when adding features. In fact, there's sometimes skepticism in the other direction when a feature doesn't add much more than what can be done through transpilation.

Public and private field declarations have been in development for several years, with large amounts of community input and detailed design consideration. Although I'd always like to get more community input, it's not clear to me that spending longer on the features will lead to more actionable input. Most of the pieces of feedback that I've seen over the past year are similar to earlier pieces of feedback.

@justsml
Copy link
Author

justsml commented Feb 5, 2018

I understand I'm late to the party, stage-0 would have been an ideal time...

I wish these proposals were unbundled - I feel very different about the cost/benefit of each feature. (Instance members x = 10 👍 )

I bet you're tired of debating the virtue of the feature, I understand, but saying no one is forcing you to use a feature is a kinda cop out... of course thats true.

Unless you're the lead architect or lead/whatever you do have to follow the syntax & styling that's decided for you. In a practical sense that means ~90% of devs are 'forced' to use some subset of the language.

Soon every company/project will develop vastly different styles of JS. Far more so than today. This will add a lot of friction to onboarding, debugging, accepting PRs (telling everyone to examine the js feature style guide 🤦‍♂️ ).

This is the current situation I've experienced in last 2 months:

  • Company A: Uses Generators, Proxies, Getters/Setters, Classes w/ extends
  • Company B: Uses Promises, Async/Await, Factory Functions, Zero Classes
  • Company C: Uses Node-style Callbacks, EventEmitters, Classes w/ all the 'features'

This is only going to get more difficult to wrangle as scope creep sets in for TC39.

These are differences that cannot be auto 'fixed' by eslint. Just 'errored' about.

Do we really want to keep balkanizing the ecosystem? Especially for a 'feature' we've been fine without for so long. Just because it's difficult to achieve real private members & ppl may use undocumented features, does that really make the feature invaluable?

Slightly related: TCO is a far higher priority IMHO, with virtually no impact on the semantics on the language.

Compared to the private members proposal syntax, which adds plenty of gotchas & new ways you must think of scope, plus this: this['#x'] !=== this.#x - this is a heavy burden on the languages' feature set.

@ljharb - my regex-fu is super strong 😉 😆

@ljharb
Copy link
Member

ljharb commented Feb 5, 2018

Whether something can be autofixed or codemodded or not isn’t relevant; the vast majority of the necessary things eslint checks can never be autofixed.

We have absolutely not been fine without private instance fields - there are millions of APIs that needlessly expose internal implementation details because they lack a good per-instance option. node.js itself has even been broken once by npm removing a property it considered “private” - having true privacy is critical.

@littledan
Copy link
Member

The point of standards is to make a single definition of what it means to have "all the features". That means, in this case, more features, but ultimately less diversity, so you have a single environment where this feature is definitively present. There will always be different coding styles, however; I don't think we can control that.

This proposal is at Stage 3. If we split it, we'd have multiple Stage 3 features. I imagine what you really might want to do is demote this to an earlier stage. That'd take a pretty convincing argument--TC39 thought long and hard about this feature, went through many revisions, and ultimately approved it to Stage 3. We'd need a new, killer argument to justify demoting it.

@justsml
Copy link
Author

justsml commented Feb 5, 2018

The autofix thing is relevant to some - mostly because it makes for a much smoother transition between projects (esp switching between corporate & open source projects).

I realize years of effort have gone into this, and I appreciate it - I used to want private members years ago.

I simply don't have this problem after using JS for so long.

I use clousures to effectively hide all 'private' methods. I know the FAQ highlights shortcomings w/ this pattern - and specifically sharing private members between same types always seemed like a dubious use case - this complexity aint free.

It's not that I want to demote it down to stage-2, I just want to slow the relative breakneck speed of these changes.

In my informal polling, devs I talk to (at work, meetups, etc.) do not realize this is what is happening to class syntax. They think I'm talking about the original class proposal, roll their eyes and say "that's been decided" - when I show them what's coming it is often met with something ranging from shock-to-horror. I am surprised that more people seem to know about the Regex additions to ES2018.

Since you can't unship a feature, I hope it idles at stage-3 a while longer. At least until more devs know whats coming...

@justsml
Copy link
Author

justsml commented Feb 5, 2018

To me this is a case-study in scope creep.

Everywhere I look in the FAQs/discussion/meeting notes it looks like someone is pushing an edge-case "need" into classes

The other newish class features like static, getters/setters, and instance members are fine by me - as they add a limited amount of syntactical overhead - with only a little more runtime/cognitive load.

Private members are a whole different consideration - I bet some dogecoin that it's more complexity than all other class features combined.

😇

@littledan
Copy link
Member

I don't think private fields and private methods are edge cases. As you say, their motivation is documented. It will still take some time for this proposal to get to Stage 4--we still don't have two implementations. I don't see any action to take for this bug.

@bakkot
Copy link
Contributor

bakkot commented Feb 5, 2018

It's not that I want to demote it down to stage-2, I just want to slow the relative breakneck speed of these changes.

Just a note on this - we've been talking private members in classes since at least 1999. We've been talking about about this specific proposal for something like three years, including a great deal of time in committee. I appreciate that if you're not closely following the process it might seem like it's all happening of a sudden, and there's probably some way we could do messaging better (though I'm not entirely sure how), but this is really, really not a sudden or rushed change.

@justsml
Copy link
Author

justsml commented Feb 10, 2018

@littledan
Was this 'silently' split? Clarified?
Was a readme.md force-pushed with an old version?

Thanks for listening y'all!!!

@littledan
Copy link
Member

@justsml What split are you referring to?

@justsml
Copy link
Author

justsml commented Feb 10, 2018

@littledan
There was a Readme update on several of the class proposals that had been reduced to a paragraph saying things were combined, linking to a new repo.

@littledan
Copy link
Member

@justsml Yes, the public and private fields proposals were combined. This was announced at TC39, and the README update reflects this.

@justsml
Copy link
Author

justsml commented Feb 10, 2018

I was just looking for the language that prompted my 'concern' in the first place.... Looks like each individual proposal's README now includes details about every other class feature (decorators, public, private, etc).

Just wasn't sure if I was imagining the README change as the date stamps aren't what I expected.

@littledan
Copy link
Member

Yeah, you can look at old READMEs in the git history.

@justsml
Copy link
Author

justsml commented Feb 10, 2018

I've used git before 😇 .

That's why I was specifically asking if something was force-pushed an update I can no longer see? Or if I was looking at someones fork potentially.

Was there a README that only had a paragraph or 2 of text talking about the merger of proposals?

I'm not fishing for credit for updated language - I just want to know if I'm going crazy/losing my memory 😸

@justsml
Copy link
Author

justsml commented Feb 10, 2018

I might just be looking in the wrong repo...

@justsml
Copy link
Author

justsml commented Feb 10, 2018

Btw, @littledan thx for answering on the weekend ❤️

@littledan
Copy link
Member

I don't remember force-pushing myself, and the class-public-fields repository seems to have a bunch of history here. There's probably room for improvement in these explainers. PRs for improving documentation are very welcome, and feel free to keep asking questions about the history of how things came to be here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants