What are the advantages and disadvantages of Angular.js vs. Elm?

I'm looking into doing some reactive programming in the browser and comparing angular.js (http://angularjs.org/) with Elm (http://elm-lang.org/).

What are the relative benefits / problems with each?


Solution 1:

I think they are different beasts, IMO, although they do share the goal of being as declarative as possible, and an attitude of "hey, let's do things They Way We Should Be Doing Them".

Now, with AngularJS you're still in "familiar" territory. Meaning, you write some markup over here, write some JS over there, and then you serve it. Same workflow as usual. The "innovation" of AngularJS, as far as I can tell, is that it extends HTML with additional element types so that you can declare a lot of aspects and behavior of your app right in the markup, and then its JS lib contains the necessary machinery to give you templating, routing, data binding, form validation, localization, etc. (...writing this makes me wonder if perhaps AngularJS suffers from a bit of bloat.), which makes for a very complete web app dev framework. And it pushes you to write your code in a declarative style.

With Elm you're really getting into new (if you have a "typical" HTML/JS frontend dev background) territory. It's a different way to do (and think of) GUI development. You will write in a completely new language – made specifically for creating GUIs in a functional reactive programming way – and ideally you'll never deal (at least not directly) with any of the traditional DOM APIs. Elm comes with a sort of "standard library" that gives you tools to create and manipulate graphics/text/etc through time.

Your Elm language code will describe, in a totally declarative way, what you want your GUI to look and behave like as time goes by and events (user input, etc) occur. Then, it will compile it all to HTML/JS/CSS in order that runs on the browser.

Elm is very young, too. It's up to you and your needs to decide whether that's a disadvantage or not.

I guess to me choosing AngularJS is just the same old "hey let's try this JS lib/framework thing"-process we're used to in the JS world. You grab the lib files, add them to your project, and start using its API. Whereas with Elm, you have to start approaching your workflow and solutions to problems differently.

AngularJS gives you a lot of structure, and it's different from, say, Backbone.js, but at the end of the day, if you want to do some advanced GUIs and graphic behaviors, with AngularJS you're back to writing a ton of plumbing boilerplate stuff that you wouldn't have to write if you were using Elm.

On the other hand, if you have to develop and release a large web app right now, with the usual GUI widgets we've been using on the web so far, I'd be inclined to say go for AngularJS because it's more stable.

Having said that, I think Elm is the most interesting and promising things happening in the frontend dev world at the moment. And, if I had to develop and release some graphics-heavy stuff today, I would go for Elm, since one can do very complex GUI stuff with it in very few lines of code. But I'd have to get into its mindset first, and deal with the fact that it's very young and integrating it with an existing JS frontend codebase might not be easy or even possible atm.

Edit:

As of March 2015, Elm is a lot more robust, and there's great tooling for it (time-traveling debugger comes to mind).

Angular remains being, well, more of the same. I should note that Angular's approach, with its a-ton-of-things-happen-whenever-a-model-changes approach ("2-way data binding") makes it totally unsuitable for things such as browser-based games, whereas Elm excels at games and advanced GUI stuff that needs to perform well. Additionally, Elm now has a fast (using the virtual dom diff'ing approach) HTML library, for when you need to speak in HTML.

My bone to pick with Elm is that its type system isn't as expressive as e.g. Haskell's. Some may think that this is asking for luxury, but on the contrary, it's about losing the ability to express basic functions. Especially us, seasoned JS programmers, suffer from not-expressive-enough static type systems, because it means that polymorphic code that we're used to easily express in JS, becomes a type error in Elm, due to lack of e.g. rank-2 types.

Fortunately, all the "wishlist" features that are missing in Elm, are not there because of ongoing discussion about them and their alternatives. So it's a safe bet that they (or the best alternatives) will eventually make it to the language.

Solution 2:

Both complex static graphical layouts and interactivity are much more simple in Elm than in HTML/CSS/any JavaScript framework. With Elm, the accidental complexity lies in the types, but it is well worth learning about them - they help understand, debug and modify software better, and they should be already familiar to you if you come from a functional programming background. Note that you can also embed Elm in HTML/JS, so in theory, you can migrate gradually.

Solution 3:

Elm is a lot more opinionated than Angular, and notably with respect to state management. If you find state becoming an issue in a conventional Angular app, then you might be tempted to look towards centralised (monolithic state) using a Redux style approach, with ngrx coming quickly to mind.

Elm epitomises the notion of a central immutable state, and was an inspiration for Redux. Elm enforces a single immutable state with a pure update (reducer) function. In my view that makes handling state in a highly reactive web app much, much simpler than the confusion that can arise using an OO-like pattern in Angular.

Elm is great for most apps, but its can become a little more complex when you want to work with external JS libraries (e.g. google maps), as its foreign function interface (ports) is quite rigid. The sort of animations needed in Material Design has also proved challenging for the Elm Architecture - that's not to say that there aren't animations, but that they take more wiring up than you might want to do.