The Two Pillars of JavaScript
medium.com
medium.com
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 )).
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.
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."
Try linking some code that does reach a solution you deem best, and good luck with your sales!
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).
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...
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.
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...
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