
Mixins, Subclass Factories, and Method Advice in JavaScript - braythwayt
http://raganwald.com/2015/12/28/mixins-subclass-factories-and-method-advice.html
======
lostcolony
This is probably a somewhat fringe sentiment, but reading this reminds me very
much of [http://codeofrob.com/entries/you-have-ruined-
javascript.html](http://codeofrob.com/entries/you-have-ruined-javascript.html)
(I was making very similar comments while reading this)

I'll readily admit I'm biased against OOP; I much prefer functional
approaches. When I write Javascript, it tends to be pretty functional, with
minimal OOP conventions.

But that said...all the problems this addresses are self-inflicted problems.
The very start of the article even says as much, "Mixins solve a very common
problem in class-centric OOP" \- that is, "these problems are only problems
because you want to write Javascript in class-centric OOP", something it
wasn't really designed for (and the constant attempts have led to Ecmascript 7
and the 'class' keyword, which I find myself shaking my head at; again, see
prior link, at trying to make Javascript feel 'enterprisey').

Find another way to go about it maybe? The subclassFactory example he
gives...if I saw that in a code base I'd want to punch someone. Because
without the writeup he gives, I'd be staring at it, and the functions it
calls, for a good 20 minutes before figuring out what it's doing. And all it's
doing is trying to shoehorn a specific paradigm into a language not written
for it. I mean, you can do it, sure, but -why-? I don't really like Javascript
but at least I feel pretty productive in it; why would I make it harder on
myself, and everyone who reads my code after me, by trying to make it
something it isn't?

~~~
braythwayt
Perhaps the author ought to spend some time reading a book like JavaScript
Allongé and learn how Functional Programming in JavaScript is done ;-)

[https://leanpub.com/javascriptallongesix/read](https://leanpub.com/javascriptallongesix/read)

~~~
lostcolony
Sarcasm aside, I know raganwald (you?) can approach things functionally. :P My
comment isn't to imply he can't (nor that I'm particularly good at it), nor to
imply anything about his choices when writing code (as I said, he correctly
notes that this is an issue when trying to write class-centric OOP in
Javascript; this says nothing about his views on whether class-centric OOP in
Javascript is a good idea or not). And, certainly, come ES6, mixins get some
language help with Object.assign.

My point is simply that if in ES5 you have to fight this much with the
language to try and shoehorn it into a particular paradigm, maybe you've
picked the wrong paradigm for that language. And the fact so many people try,
and so many authors have written ways to try and shoehorn that paradigm into
the language (as it stands at ES5), tells me that it -really- is probably not
the best choice.

And the insistence in doing so seems like a misplaced "make it behave like
Java" that brought to mind that URL I linked.

That's not to say thinking about it isn't itself a worthwhile endeavor. That's
not to say that seeing that it can be done in Javascript isn't a point in
Javascript's favor. That's not to say there isn't a demand by people for the
language to behave this way, and that others understandably try to meet that
demand. But it is to say that it's solving a problem that is self-inflicted,
by dint of choosing to use classical inheritance in a language that was
designed to support prototypal inheritance.

~~~
braythwayt
It’s a question of taste.

To me, hierarchies of classes are not very JavaScript, but mixins written as
decorators are very JavaScript.

To me, overriding functions and calling `super` is not very JavaScript, but
writing function combinators like `before` and `after` is very JavaScript.

To me, JavaScript is about composing bunches of single-responsibility things,
not writing big things.

So to my taste, mixins and decorators are in a deep way, strongly related to
functional programming, while the sugar for stuff like classes and special
syntax for getters and setters is not.

~~~
lostcolony
That's fair, and I'd agree that mixins and decorators can be more closely
related to FP than I initially took them for.

I just tend to keep my objects as, basically, structs, and functions bound
outside of them, rather than treating them as objects, so questions of
composability in such a manner don't come up. Rather than have to write a lot
of abstracted out code to support mixins, and then know what assumptions a
mixin has about the object choosing to mix it in, there are instead just
functions; you want them then reference them, and what they take is spelled
out (somewhat more) clearly in the function header, if you can pass in the
right arguments, the function can be reused. If you want a set of functions
that all work together, then composition, sharing state, etc, falls on you,
rather than being implicit in assumptions the mixin and mixing class may make
about each other. As you say, a question of taste (especially as to what steps
you take to avoid those assumptions).

But that said, I've done similar things in merging two objects prior to
serializing them out across a REST endpoint. So there it was less a design
consideration of composable function containers, and more one of data
transformation (not that they're separate beasts; functions as data and all
that), but at the same time a lot of the complexities were avoided.

------
dexwiz
Great write up, and neat ideas. One of my biggest hurdles on learning
Javascript so far is that because definitions are so flexible, its very
difficult to pick up a code base with an unfamiliar structure. Mixins in
particular spread code between files, and the mixin itself is often hidden, or
not obvious. At least in Java, I know I can look at extends, and trace it from
there.

The decorator pattern seems like it would be pretty obvious. But its yet
another non standard way to create objects. If I saw without explanation, I
would be at a loss on how it works, or even what it does. At least method
overriding is consistent when it is baked into a language. But having to learn
a new mixin/inheritance/definition pattern for each codebase has given me
serious troubles recently.

~~~
braythwayt

      > At least method overriding is consistent when it is baked into a language
    

Right there you have one of the two great families of programming. You like
things like Python, where there is only one obvious way to do anything, and if
it isn’t obvious, you just don’t do it. These ideas are from the other family,
where you have a number of small but powerful ideas that you can combine in
various ways.

The ones that solve problems and have great timing and get some marketing
oomph establish community traction, the rest fade away. This is the UNIX and
Lisp tradition.

I can’t tell you whether one is better than the other. I can tell you that the
first thing is IBM. And opinionated frameworks. And benevolent dictators. The
second thing is startups. And libraries. And tinkerers. There’s no shame in
preferring one to the other. Both have produced great things.

~~~
dexwiz
I look forward to the day when the rest fades away from Javascript. Right now
it is the wild west in terms of pattern usage, especially when it comes to
implementing "private" variables with some scope tricks that result in
unreadable code.

------
aikah
I like what raganwald writes but let's get real here. People asked for the
class keyword because it made classes easier to write AND read. OOP with
prototypes is dreadfull, from a "clean code" perspective.

Javascript should get the same perks for mixins, because going back to
"builders" is going back to everybody writing his own flavor of the same stuff
and doesn't make things readable anymore.

Is there a mixins proposal for ES7 ?

a simple thing would be to allow multiple inheritance :

    
    
        class Foo extends Bar,Baz {}
    

just like Python

I think the Python way is the simplest one.

~~~
angersock
You know, given the sheer amount of JS that has been written successfully in
the last ten years, I think it might be worth asking: is it really _needed_ to
continue mudballing that type of stuff onto the language?

Especially with mixins and things, it's really easy to add so much magic to
the code that getting up to speed on what something is doing becomes
prohibitive. It's really great for flavor-of-the-week frameworks, but long
term maintenance can become a nightmare and proper performance tuning
difficult.

Then again, maybe we don't care about maintenance and performance anymore.

~~~
aikah
> You know, given the sheer amount of JS that has been written successfully in
> the last ten years, I think it might be worth asking: is it really needed to
> continue mudballing that type of stuff onto the language?

That's a good question. If it helps write a specific pattern and make it more
readable I think it's worth it.

People are going to write these stuff anyway, why not help making things more
readable for anybody else ? it's not going to change the nature of javascript,
I'd argue that things like proxies or decorators are far more questionable
than multiple inheritance, yet they made/are making it to the spec.

Nobody can deny Python code looks usually clean and mostly readable. Nobody
can deny that Javascript code is often unreadable because ES3/5 developers
didn't have the syntax to convey specific ideas in a eloquent way(thus all the
prototype plumbing, module pattern and co that made js code look like
brainfuck,don't even get me started on ninja coding).

~~~
marcus_holmes
Javascript is not readable to you because you're attempting to apply OO
patterns to it.

Javascript is not an OO language, it doesn't work like that.

It is an incredibly powerful and elegant language, please take the time to
learn how it works and appreciate its beauty. Then by all means make
suggestions about how it should be changed. But only then, please.

Not all languages would be improved by being "more like Python".

~~~
aikah
> Javascript is not an OO language, it doesn't work like that.

What ? it certainly is today with the "class" syntax. Or it is like saying
neither Ruby or Python are object oriented.

> elegant language,

Elegance is in the eye of the beholder

~~~
angersock
Minor point of order...Ruby is OO because it very much follows the Smalltalk-
style message-as-function-invocation pattern.

Javascript (at least before ES6) is perhaps too minimal in its language
affordances to qualify for "true" OO status.

