15 comments

[ 4.1 ms ] story [ 39.6 ms ] thread
> “The `class` keyword will probably be the most harmful feature in JavaScript."

I'm glad I'm not the only one.

One of the reasons Javascript became so popular is that it took many of the properties that Lispers have been extolling for decades (minimal syntax, light-weight, meta-programmable, functional, composable), but wrapped them in a familiar-enough looking package that even beginners can Get Stuff Done. (Which is where Lisps have historically failed.)

I'm hoping the future of Js will continue in this direction, but looking at ES6 and Angular, it looks like too many people are trying to turn Javascript into Java.

The heart of Javascript is simplicity and power. Arrow functions and modules are a great addition. Maybe with enough support from the community, instead of more syntactic sugar and complexity, ES7 will adopt macros (http://sweetjs.org/) and a type system (e.g tcomb ( https://github.com/gcanti/tcomb )).

Off topic: tcomb looks insanely cool. Thanks for pointing it out. Though HN is including one of the parens in your link, which is messing it up. Here's a pristine version for the lazy: https://github.com/gcanti/tcomb
> "I'm glad I'm not the only one"

You're not the only one, but we're being steamrolled by the Java crowd and I'm afraid that we're in a losing position. Angular is the first of many to come.

Spoiler alert: there's no code in this post, and it ends with a link to an IGG campaign.
Google "classical inheritance harmful" and you'll find articles with plenty of code examples. The point of my article was not to bog the reader down in implementation details, but to communicate high-level concepts in rant-style prose. ;)

Here's a bit of code, ranting against the same problems, but coming up with different solutions: http://berniesumption.com/software/inheritance-is-evil-and-m...

Here's a nice quote:

> I once attended a Java user group meeting where James Gosling (Java's inventor) was the featured speaker. During the memorable Q&A session, someone asked him: "If you could do Java over again, what would you change?" "I'd leave out classes," he replied. After the laughter died down, he explained that the real problem wasn't classes per se, but rather implementation inheritance (the extends relationship). Interface inheritance (the implements relationship) is preferable. You should avoid implementation inheritance whenever possible.

Link (with code samples): http://www.javaworld.com/article/2073649/core-java/why-exten...

More ranting: http://sebastiansylvan.com/2010/12/03/implementation-inherit...

Fairly decent list of rants, with some pointed quotes from software development luminaries:

http://harmful.cat-v.org/software/OO_programming/

As for the IGG campaign, yes, I'm selling something. I make a living writing software, and teaching other developers how to write software better.

That has nothing to do with the validity of my arguments, except to underscore the fact that there is plenty of real experience behind the words.

"The way to be a 10x engineer is to teach 5 other developers how to be 2x engineers."

Thanks for the links, that's not a search phrase I would instinctively write. I don't understand why you couldn't include examples to illustrate your point in the blog post, you're addressing coders after all. I can't find anything negative about doing that. As is, your post reads like a paygate to your book.

Try linking some code that does reach a solution you deem best, and good luck with your sales!

The benefits of prototype inheritance have always seemed rather dubious to me. The programmer wants to express that there are a bunch of objects with the same structure and behavior; the compiler needs to know which objects have the same structure and behavior. Forcing both sides to pretend that each object is a unique and special snowflake when that is both counterfactual and inconvenient for all involved seems pretty silly. That said, C++/Java-style class-based o.o. is no panacea either and having both things in a single language is just crazy.
> That said, C++/Java-style class-based o.o. is no panacea either and having both things in a single language is just crazy.

Actually, there is just prototypal inheritance. The whole `new` operator thing (as well as ECMAScript 6 classes) is just syntactic sugar over prototypal inheritance.

But yeah, it's crazy that this had to be put in just to attract users (in the 90s, to make it look more like Java; along with method names etc).

> Forcing both sides to pretend that each object is a unique and special snowflake when that is both counterfactual and inconvenient for all involved seems pretty silly.

That's not at all what prototypal OO does. A prototype in JS is very simple: It's an object, just like any other object. It's not pretending to be anything else but an object.

When another object links to that prototype (using the `new` mechanism or `Object.create()`) that object is not pretending to be a unique and special snowflake. In fact, exactly the opposite is happening: It's delegating everything that is "the same" to the prototype it references.

The primary advantage to that is a simple matter of memory conservation. Otherwise, you might as well just copy properties from the prototype to the new object. Some functional languages do essentially that every time you create a transformation, because state in some functional languages is immutable.

Under the hood, such languages are actually just copying references to shared data, which acts very much like prototypes, practically speaking. The difference being that the language users are not exposed to the mechanism.

These are very different paradigms from classical inheritance where everything you extend creates an "is-a" relationship and a single parent object hierarchy. It's a strict tree system.

Prototypes in JavaScript do nothing of the sort, because you can use dynamic object extension to build up a prototype from as many sources as you like. The practical upshot is a lot more freedom, no more need for hierarchies, which eliminates the need for "super" calls, which reduces coupling -- the children have no knowledge of the prototypes that have been composed together to create the API of the child.

See "Prototypal Inheritance with Stamps" for more detail: http://ericleads.com/2014/02/prototypal-inheritance-with-sta...

Interesting.

I've been working with JavaScript for the past few months in a class-heirarchy environment (Educational games using a proprietary engine), and it seems to be working pretty okay.

I guess it might be because the hierarchy isn't very complex as far as I'm concerned. A lot of the ugliness in the engine is abstracted away from me as a game developer.

> it seems to be working pretty okay.

These things have a tendency to balloon out of control over time. I've seen class hierarchies start out very benign. Convenient and well-designed, even.

But as the codebase grows and new objects need to be modeled, it inevitably gets stretched beyond the limits of its original design, and that's where things start to crumble.

Also, the more layers of inheritance there are, the more brittle the code becomes due to tight coupling between child and parent classes. Super calls start to turn into a tangled nightmare.

Here's a different perspective on the same topic: http://berniesumption.com/software/inheritance-is-evil-and-m...

Agree 100% with this article. I've done Perl, Java, and NodeJS applications. The absolute worst code I've ever seen was Java, which with OO and typing adherents say leads to maintainable code. Trouble is, most Java engineers are no better than Visual Basic programmers. Functional Perl and JavaScript are beautiful things. And by staying away from classes, you get to the more fundamental - data structures and transformations.
Actual two pillars: massive user-base and a fear of change.
JS has some great features, but I sincerely hope we move on from JS as soon as possible. IMO, it's pretty well done its job, and it's most interesting now as a compile target (particularly with source map support!)

I'm not a fan of C++ (I'm a recovered user and abuser of C++), but I AM a fan of many things built with it, including the Unreal4 engine, which runs great when compiled to JavaScript. =)

I've been using and really enjoying CoffeeScript, which, IMO is what ES6 should have been. I also like to fiddle with Haskell, and there is a Haskell to JavaScript compiler, too.

Whatever catches fire after JS, I hope it has these features:

* Dynamic object extension + better abstractions around common prototypal OO patterns -- maybe something like built-in stamps? * Lambdas with closure * Immutability by default * Functional utility belt built-in to the core with a single API around streams, continuous data sources, and collections including arrays and objects/associative arrays/touples. This API should behave the same way regardless of whether data flows through the functions one value at a time (i.e. iterables / generators + yield), in response to emitted events (e.g. Node-style streams), and periodically sampled values (continuous data sources such as audio, electrical signals, UI inputs, even time-independent things like vector graphics, etc...). * The necessary primitives to support the above. Functor literals, promises, etc... * A better single number type for most use cases * The ability to easily define custom binary types, for implementing things like low level binary protocols more easily

Yes, I guess the biggest problem is that writing JS manually is still mainstream. Perhaps browsers should somehow detect such code and forbid/warn it as unsafe.