
Classes Are Making Me Sad - acconrad
https://gist.github.com/bathos/b134b7559161ddb80e53b3ee4cca253f
======
taurath
I'd love if we could have a better conversation about JavaScript than "the
language is bad and if you like it in any way you should feel bad" but
seemingly not today.

To create a bit to the discussion, I feel like the class abstraction in ES2015
is mostly a mask that doesn't do people any favors - it makes one think they
know what is happening but leads experienced programmers to false reasoning
and much head banging. I've highly preferred a more functional style for most
of my projects and teams - I wish there were better standard tools for
enforcing style, as organizationally it's harder to get everyone on the same
page than with more mature OOP tooling (which OOP patterns/strong typing makes
easier to build).

~~~
rocqua
Really, the largest problem I see in javascript is exactly how it doesn't have
a lot of features to enforce style.

Sure, there is some other wonky stuff, but the ease with which one can write
bad javascript is the core issue.

~~~
treehau5
This is a relatively solved problem with a proper .eslintrc and a style guide.
You can pick two of the most popular -- airbnb or standardjs, npm install
their eslint rules, and go on your merry way. Rolling your own and/or
extending these is relatively simple.

------
gadtfly
Whoever at Netscape vetoed Scheme as the browser language should be on trial
in The Hague.

~~~
kazinator
The short story has it that it was some Java-pushing dickheads from Sun
Microsystems.

~~~
kazinator
You may dislike my tone, but it is basically factual.

[https://news.ycombinator.com/item?id=9098367](https://news.ycombinator.com/item?id=9098367)

Eich> I joined Netscape on April 4, 1995, to "do Scheme in the browser".
Immediately I was out of luck on several fronts:

Eich> [...]

Eich> If there was to be a "scripting language", it had to look like Java.

[https://news.ycombinator.com/item?id=2786720](https://news.ycombinator.com/item?id=2786720)

Eich> Remember, I was recruited to "do Scheme", which felt like bait and
switch in light of the Java deal brewing by the time I joined Netscape.

~~~
LyndsySimon
Cool. This explains why the better I understood Clojure, the more my
Javascript started to look lispy.

------
shp0ngle
Every time I think I understand Javascript, I read something about its
prototypes and constructors and how 'new' and 'this' works and I am lost
again.

The thing I like about classes is I vaguely understand what is going on and
why, coming from Java and similar. So I am using them, together with Flow
typechecking.

I am not saying the javascript prototype logic is bad, just that I never
understood it, even when I work in Javascript for years.

Sometimes I understand, for a brief moment, "how", but never "why".

~~~
Lazare
> Every time I think I understand Javascript, I read something about its
> prototypes and constructors and how 'new' and 'this' works and I am lost
> again.

Prototypes, constructors, and context are not that complicated; I encourage
you to keep reading and trying things. You may be surprised how quickly you
end up "getting" it.

> The thing I like about classes is I vaguely understand what is going on and
> why, coming from Java and similar.

No. The class keyword in JS is syntactic sugar around the same prototype stuff
that already existed. It does not work like it does in Java, and you will not
understand what it's doing unless you understand how the class keyword
translates directly into manipulating the prototype chain.

Which, as above, is easy! But if there's one _actual_ problem with the class
keyword it's that it makes people who know Java think they understand JS
inheritance.

The class keyword _DOES NOT CHANGE YOUR CODE_. If you didn't understand what
was going on before you used the class keyword, you don't understand it after
adding it in. (Conversely, if you actually do understand how the class keyword
works, then rejoice, you now understand how prototypes work...)

~~~
coldtea
> _Which, as above, is easy! But if there 's one actual problem with the class
> keyword it's that it makes people who know Java think they understand JS
> inheritance._

Which is totally fine, as for all intends and purposes the behavior is the
same. You create new instances, and you call methods on them.

The "movable" context (this) will be a little surprising, but for everything
else one can write JS for decades with ES6 classes and "OOP", without having
to know how the prototypes, objects and functions they de-sugar to work.

~~~
LyndsySimon
> Which is totally fine, as for all intends and purposes the behavior is the
> same.

Nope :) They're _apparently_ the same, which is not the same as "the same".

> The "movable" context (this) will be a little surprising, but for everything
> else one can write JS for decades with ES6 classes and "OOP", without having
> to know how the prototypes, objects and functions they de-sugar to work.

That's just the thing though - there isn't a "movable context", there is only
binding. Binding usually happens implicitly, and most of the time things are
implicitly bound to what you expect them to be if you're not aware it's
happening.

... then comes the moment that you're in an instance's method, and `this` is
pointing to an event instead of the object. Oh, boy.

In my experience that moment comes much more often than once every few
decades.

------
codecurve
Wonder what the language would now look like if we had some dedicated syntax
for Object.create instead of hiding the underlying prototype mechanism under
the familiar class syntax.

    
    
        typeof (class {}) === "function"
    

This is almost guaranteed to be a future WAT[1] moment for the next generation
of JavaScript programmers.

I can already see that a big part of the appeal for classes is that they keep
your code looking neat and succinct (as opposed to throwing .prototype and
Object.create all over the place.

I'd much rather be writing code that looked something like the below, than
having to think about super, static, own properties, constructors, private
fields etc.

    
    
       // provided by some view library
       let Component = {
         state: null,
    
         setState(state) {
           Object.assign(this.state, state);
           this.forceUpdate(); 
         }
    
         // ...
       }
    
       let Counter is Component {
         get state() {
           return { count: 0 };
         },
    
         inc() {
           let { count } = this.state;
           let { step } = this.props;
           this.setState({ count: count + step });
         },
    
         render() {
           let { count } = this.state;
           return <button onClick={this.inc}>{count}</button>;
         }
       }
    
       render(<Counter step={2} />);
    

Although it introduces a new keyword, the abstraction ends up being minimal,
because it's just a sugar for the existing Object.create.

    
    
       // let Counter is Component
       let Counter = Object.create(Component);
    

This is obviously a very half baked idea, but I have programmed quite happily
with Object.create for a long time without ever _needing_ to use classes. If
we had better tools for working with prototypes then maybe we wouldn't have to
pretend the language had classes instead.

[1]:
[https://www.destroyallsoftware.com/talks/wat](https://www.destroyallsoftware.com/talks/wat)

------
ng12
As someone who works mostly in React I've never found a use for classes. It's
a contentious, messy feature that solves problems I don't have.

I used Coffeescript classes in the old jQuery/Backbone days and they were
useful only because the rest of the ecosystem was so terrible.

~~~
Lazare
> As someone who works mostly in React I've never found a use for classes.

You can't NOT use classes if you use React. [Edit: For components with state]
your syntax choices are:

    
    
        Foo = React.createClass({})
    

Or:

    
    
        class Foo extends React.Component {}
    

But both are examples of JS classes; it's just a question of whether you use
the class keyword or not. Every React component [Edit: with state] is a class.

Edit: Fixed silly error; obviously you can use stateless functional components
and I do all the time, but you can't avoid classes with React.

~~~
shepmaster
I tend to heavily favor functional components[1]:

    
    
        function Welcome(props) {
          return <h1>Hello, {props.name}</h1>;
        }
    

or a little nicer:

    
    
        const Welcome = ({ name }) => (
          <h1>Hello, {name}</h1>
        )
    
    

[1]: [https://facebook.github.io/react/docs/components-and-
props.h...](https://facebook.github.io/react/docs/components-and-
props.html#functional-and-class-components)

~~~
Lazare
Sorry, typed too fast. Edited my answer to clarify.

------
dongslol
JavaScript is not an object-oriented language, but a prototypical one. JS
"classes" are really an attempt to use syntactic sugar to beat one concept
into another. This is inherently ugly.

For anyone convinced they hate JS, I encourage looking through Crockford's
_JavaScript: The Good Parts_ , in which he talks about the idea mentioned
above, before swearing off JS forever.

~~~
dragonwriter
> JavaScript is not an object-oriented language, but a prototypical

Prototypical languages are a subset of OO languages, despite the fact the the
industrial popularity of a handful of class-based OO languages (especially C++
and it's descendants) starting in the late 1980s have made it so that many
people confuse OO with specifically class-based OO.

~~~
munificent
The first object-oriented languages—Simula and Smalltalk—were class-based, so
when "object-oriented programming" was coined, it implicitly included classes.
_Every_ OOP language had classes.

Only later when Self came out was the term broadened to include languages
oriented around objects _without_ classes.

Sure, we need to be more precise today and refer to "class-based object-
oriented" and "prototypal object-oriented", but that's not a fault of the
class-based languages. They laid claim to the general term first.

Before horseless carriages, all carriages had horses, so it seems unreasonable
to expect people to have presciently called them "horseful carriages" even
before automobiles were invented.

~~~
Diederich
[http://userpage.fu-
berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay...](http://userpage.fu-
berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en)

"OOP to me means only messaging, local retention and protection and hiding of
state-process, and extreme late-binding of all things."

Simula has classes, but Alan Kay's "object oriented" wasn't about classes at
all.

------
golergka
I always thought that Javascript kind of is modern Lisp, apart from all the
parens. Radical freedom means everybody implements their own classes,
promises, all kind of stuff that is out of the box in other languages — which
makes us happy because we can play with it, but then makes everybody unhappy
when we try to bring our toys together. And when somebody gets their way in
deciding what is the _right_way_ to play, all the rest of us get even more
unhappy.

------
SFJulie
Me I am sad about how unreliable comparison operators are.

We fix equality by using === instead of ==. == is so bad that it is not
transitive if a==b && b==c you are not sure c==a

And everytime we use <, <=, >, >=, cmp we are back at using == implicitly,
which triggers so many problems and bugs (and sort relies on them, thus sort
is also broken).

If a language cannot do simple math correctly, it should never be used for
stuffs related to commercial transactions or security... anything serious.

------
Willson50
Javascript is making you sad.

------
camus2
> Classes Are Making Me Sad

And they are in the spec. It's too late to be sad about that, people are going
to use them and they should.

------
omegbule
There isn't really a need for classes...

------
guilhas
Comunism for you then. Let's end the class struggle!

PS: This comment does not intend to be productive in any way.

------
politician
Try Elm?

~~~
mixedCase
Not OP, but I just finished a small trial phase with it.

There's no straightforward way to make nested record updates. You have to
write separate setter functions for every step of the way.

If you don't list every single mutation in a single type, and have a single
update function to handle them all, you're in for an exhorbitant amount of
boilerplate to wire it all. Long, single file types and functions with
Objective-C style namespacing are idiomatic.

All is good error wise, until you have to use the escape hatch to JavaScript,
in which case good luck building a separate castle of abstractions to fit both
of them together and debug it.

There's also the fact that the language creator has to bless a set of bindings
before they're allowed to be packaged and uploaded. I do not know how this
works out in practice, but it certainly made me raise my eyebrows and not in a
good way.

In summary: It's a promising language, but using it to build large codebases
either involves techniques the community doesn't know about or it's an
exercise in masochism. Maybe in a few years it'll be good.

~~~
politician
Thanks for the insight; we're also evaluating Elm, but our code base isn't
large, and we committed to using flat records. Good point about the nested
record handling.

~~~
mixedCase
For what it's worth, I am analyzing it again after making a small prototype of
the application I needed it for but using Vue + Vuex. It's helped me put in
perspective the amount of boilerplate needed by Elm, and now I'm not so sure
that particular downside is as big compared to the alternatives as to
disqualify it...

I'm going to give it another full week before going one way or the other.

------
BuuQu9hu
If only ES were more like E or Monte, where there are no classes and no
`this`.

------
bekimdisha
Javascript is making you sad.

------
bradmwalker
How much energy will be spent thrusting this regressive pig?

~~~
CharlesW
More than will be spent thrusting all other barnyard animals combined?

------
d--b
Dude classes are making you sad? Man, you should shield up, _a lot_ of things
beyond classes are going to make you sad. Classes and javascript are a history
between 2 different clans fighting together and no one winning, but it's still
javascript. Not a huge deal if it's shittier than it already is. I like the
language don't get me wrong, but there is so much in there that's unpleasant,
that another construct shouldn't affect you much.

------
throwawaysed
Having used JS along with somewhere north of 10 other languages over the
years... JS is the most painful, even moreso than Perl which was close.

Classes and objects are 100x better than the crap they've come up with to fix
JS so far so stop complaining.

Oh no it's not functional???!!! Javascript never was. It was always supposed
to be an OO language the implementation is just shit. For the love of God
everyone just shut up and let them fix it. Trying to change JS from what it
was meant to be into something else entirely is just going to make things even
worse

