Tuesday, July 23, 2013

My Perspective On Ember And Backbone

I wrote better software with Ember than I did with Backbone, and it's taken me a long time to get comfortable with that -- even after writing my Ember book -- but I've figured out why.

I didn't want to admit to this fact because I didn't want it to be true. Backbone prioritizes simplicity and transparency, while Ember holds your hand through a lot of the scary parts of building an app. When I was first learning Ruby, a whole subgenre of "Ruby vs Java" blog posts argued over Java's limited feature set -- a deliberate attempt to hide the hard parts of development from junior devs -- vs. Ruby's "give them enough rope" attitude, where you can do almost anything. Paul Graham's writing on Lisp entered the discussion, and convinced me that it's better to work with ready access to all the hard corners and sharp edges.

In server-side frameworks, most of my experience is with Rails, and Rails takes a lot of stuff out of the picture, allowing you to focus on your application's logic. Ember does something similar, but where Rails takes stuff out of the picture, Ember takes stuff out of your control. If Rails whisks something backstage for your convenience, you can always follow it backstage and dive into any details you want. Once Ember takes something out of your eyesight, it's just gone.

You sacrifice both flexibility and autonomy when you let that happen, and I don't like sacrificing either of those things. Meanwhile, Backbone's philosophy is all about giving you enough rope. It's small, it's simple, and it does not come with batteries included. It's quick to read, and if you don't understand what you're reading, that's your problem.

So I felt like Backbone had a fundamental philosophical superiority, so if I wrote better software with Ember than I did with Backbone, that didn't say anything good about me as a developer. And for a long time I've been thinking that if I truly understood evented programming, GUIs, and browsers, I'd be better with Backbone than with Ember. (I might be overthinking the problem here, but that's kind of what we do.)

There's another reason I felt Backbone should have been superior, even though Ember got me better results personally, and it's this other reason which changed my mind.

Backbone was released in 2010. I first worked with MVC JavaScript in 2007 or 2008, when I built my own little experimental app. I did this because in 2005 or 2006, I had given a presentation at a little BarCamp in Albuquerque explaining why I thought MVC JavaScript frameworks would one day exist. The MVC JS app I built in 2007/08 was not amazing by any stretch of the imagination, but I can at least claim some foresight points here. And I've been working mostly with Ruby since 2005, so a lot of my energy in this little MVC JS experiment went into designing the right objects.

So when Backbone came along, one of the major things which impressed me is that it wasn't much more code than my little experiment, yet it did so much more, and its object structure was very tidy. Ember, by contrast, has a relatively convoluted object structure. In fact, in my book on Ember.js, I argued that Ember uses the wrong names for nearly all the major objects that an Ember developer will work with when developing an application. I argued that the Models are not really models, the Controllers are not really controllers, and the Views are not really views.

I still stand by that argument, by the way, although of course you'll have to buy my book to read it in detail. (For now, at least; I may blog it in the future.) However, what I realized in the course of writing this book was that Ember's KVO implementation is much more important than its MVC implementation.

If you're a web developer, chances are pretty good you understood every word of the MVC discussion this far, and you're now wondering what the fuck KVO is supposed to be.

That's the whole problem with the discussions which people have about JavaScript apps.

KVO stands for Key-Value Observing. It's a particular approach to live data binding. Ember provides live data binding, Backbone provides live data binding, Angular provides live data binding, and Knockout does too. It's basically impossible to implement an elegant or even useful JavaScript app framework for the browser without live data binding.

I obviously have a general interest in JavaScript app frameworks. I'm very interested to play in the near future with ClojureScript and Fay. ClojureScript is a subset of Clojure which compiles to JavaScript, and Fay is a subset of Haskell which compiles to JavaScript. In either case, if I'm writing an in-browser application with a functional programming language, I won't need MVC, because it won't be a meaningful or useful concept in the context of the functional paradigm, but I *WILL* need live data binding. This is because live data binding is, in my opinion, an essential, non-optional component of any useful JavaScript application framework, while the MVC design pattern might just be a nice thing to have.

After all, none of the MVC web frameworks actually use MVC. They all have their own MVC-ish variation instead. It almost seems that MVC isn't actually a perfect fit for the problem space, but people are trying to make it fit anyway.

I think people overvalue MVC, in the discussion about JavaScript web app frameworks, for two reasons. First, there's an old saying that generals are always fighting the last war, which basically means that strategic thinkers often fall in love with particular strategies, and fail to notice when there's been a major change in the criteria for evaluating those strategies. Second, there's a much more prosaic factor: David Heinemeier Hansson is an incredible salesman. He sold the entire web dev world on the concept of MVC, and did so with such effectiveness and thoroughness that web devs still frame questions in terms of MVC, even in situations where MVC is not the most important factor. I think this is one of those situations.

Backbone has a superior object design to Ember. I can barely even call it a matter of opinion. There's great clarity, great simplicity, and the objects are quite simply what they claim to be. I can't say any of those things for Ember. But Ember has a system for handling live data binding which is powerful and easy to use. Backbone's system makes you do a lot of the heavy lifting when it comes to handling events, and that's exactly the kind of lifting which is most likely to throw your back out. (At least, it was for me; your mileage may vary.)

Backbone has a much nicer learning curve than Ember, at least at the beginning stages, and I would still prefer a Backbone-esque level of elegance when building a browser app. But I found Ember's more graceful event handling made all the difference in the world when writing apps, while its confused MVC implementation was really just a speed bump for me. As for the things Ember hides from you, in theory I expected it to bother me a lot, but in practice, I got over it pretty fast.

Caveats: of course, this is all just my opinion. I only spent a few months building a few apps with each system. And speaking of "fighting the last war," I haven't yet seriously investigated Angular, Knockout, or any of the several other alternatives. There's always something new.

PS: Obviously, I want people to buy my book.