Tuesday, May 20, 2014

Lessons learned from Angular

I just realized that I completely forgot to announce here that I posted this article about lessons learned from Angular on the Mithril Blog.


There, I talk about some of the rationales for why Mithril templates are designed the way they are, and what makes them so powerful.

Wednesday, May 14, 2014

An exercise in awesomeness

I wrote a follow-up article to James Long's fantastic Removing user interface complexity article, where I ported some of the code examples to Mithril.


HN post

Tuesday, April 29, 2014

JS animations are cool again

A while back GSAP made a (at the time controversial) claim that JS-based animations are actually as fast as CSS based ones (if not faster). It's just jQuery that is slow.

Now, there's Velocity.js, which brings that GSAP-like speed back to the world of jQuery.

What GSAP showed us is that Javascript animations can be really powerful (or as it advertises, "impossible w/ CSS3"). A similar trend is that of constraint-based layout engines popping up. In the Mithril blog and docs, I've been talking about the expressive power of Javascript in the context of data binding engines and template componentization (something that has been generally in the domain of the HTML language) and this same expressive power is starting to flourish in the styling and flair arena.

It's really looking like Javascript is taking the reins away from CSS. I like this trend.

Monday, April 28, 2014

Thursday, December 19, 2013

Koa.js explained

Koa.js is a Node.js framework from the Express.js authors. The biggest feature here is that it uses ES6 generators to elegantly fix the callback hell problem that arises in sufficiently complex Node.js apps

For those who are not familiar w/ ES6 generators, here's an illustration:

Consider an asynchronous app that does several IO operations. Using the currently standard javscript callback style, an application might look like this:
app.authenticate(function(loggedIn) {
     app.fileExists("bla.txt", function(exists) {
        app.readFile("bla.txt", function(text) {
            app.sendToClient(text, function() {
                app.log("operation successful")
            })
        })
    })
})
As you can see there's a lot of nesting once you start doing several things in sequence. As it turns out, this causes all sort of problems:

  • hard to throw and catch errors effectively
  • lots of boilerplate code
  • even more boilerplate code when doing parallel asynchronous operations
  • difficult to reason about non-trivial code (e.g. what is in scope where, when there are many parallel things happening?)
ES6 generators are basically functions that can pause and later restart from where they paused. The syntax is the same as a regular function, except that it has an asterisk before the function name, and that it allows the `yield` keyword to be used inside of it
function *myGenerator(a) {
    yield a;
}
The` yield` keyword works almost exactly like `return`, except that if you run the function again, the code will continue executing from the next statement after the yield, instead of running the whole function again. (another difference is that yield is an expression) For example:
function *countTo3() {
    console.log(1);
    yield;
    console.log(2);
    yield;
    console.log(3);
}

countTo3(); // logs 1
countTo3(); // logs 2
countTo3(); // logs 3
With this framework, we can then rewrite that nested application kinda like this:
function *myApp() {
  var loggedIn = yield app.authenticate()
  var exists = yield app.fileExists("bla.txt")
  var text = yield app.readFile("bla.txt")
  yield app.sendToClient(text)
  app.log("operation successful")
}
So basically, every time you call `yield` you're explicitly telling the app to "go away and do other stuff" while waiting for expensive IO operations, which makes it very easy to reason about the code, and comes with all the goodness of readability, proper exception stacking, etc.

Very interesting stuff.

Tuesday, October 29, 2013

Things that suck in AngularJS (a follow-up)

So apparently my last post made it to the HN front page last night. (For the curious, it got ~35k page views in the span of one day, mostly coming from Reddit. That's roughly the same amount of traffic from all other posts in this blog since inception. Heh.)

First, I'd like to thank the people who have pointed out some factual mistakes in my previous post (specifically, the existence of $q/$q.all and $timeout.cancel). I was not aware of $q.all, so the rant ended up being useful for me to learn new things after all :)

The point I was making when I mentioned $timeout though was about orthogonality - e.g. `ng-if` not having an `ng-else` or even an `ng-if-not` counterpart to match `ng-show/ng-hide` - so hopefully my silly mistake didn't detract from the argument.

Anyways, that post is now almost 2 months old, and a lot has happened both in terms of the progress of AngularJS releases, and my own understanding of the framework/ecosystem, so I figured I should add a little update.

What is better

Documentation

In the documentation front, there's been a consistent trickle of PR pull requests on the github project to improve various areas of the documentation. Most notoriously, the directive guide is a lot more example-driven and beginner-friendly. Unfortunately, the old docs for directives are nowhere to be found now and it's now much harder to find explanations of what options are available. But it's definitely more approachable and hands-on.

Also, a variety of good 3rd party resources have been springing up. ng-newsletter.com, for example, hits the ground running with some basics and quickly ramps up to some real-world, in-the-trenches goodness.

3rd Party integration

In a similar note, there are also a growing number of projects offering support for Angular, e.g. KendoUI, the AngularCordova project, etc. This is turning Angular into a much more pragmatic pick for a vast range of projects than many of the newer slimmer frameworks in the data binding arena.

Features

The latest two releases bring a bunch of fixes and pragmatic features (e.g. $interval). On the one hand I do appreciate the new features, but on the other, these are release candidates, which by most definitions, shouldn't include scope creep or major breaking changes...

Which leads me to

What still sucks

Regressions

Regressions are still a very big weakness in AngularJS: the activity in the github issues list spiked after 1.2.rc3 was released, and many of the issues are somewhat serious integration-level problems. Their internal test suite seems to severely lack directive-interop tests, which are critical for a framework with so many interdependent components (I say they're interdependent because they all deal with $scope, often with subtle scope isolation/initialization timing related caveats). The end result is that upgrading Angular is nowhere near the plug-and-play experience of jQuery upgrades.

Other things I didn't mention before

Components

If you haven't seen this term before in the context of AngularJS, components are basically organizational directives, i.e. self-contained ng-includes. They are a mostly useful when a page hosts many loosely related, complex widgets or panels.

One weird design wrinkle is the ambiguity of directive controllers vs regular controllers. Using a directive controller in a component yields less code and clearer modularity, but it breaks the general convention of being able to find all business logic in the controllers folder and DOM stuff in directives. On the other side of the coin, using a regular controller creates more boilerplate code and makes the scoping of inputs and outputs harder to follow.

A big problem with components (and directives in general) is that they can't be used recursively to build things like tree structures. In fact, doing so hangs the browser! The only workaround for this is to use ng-include and shadow variables, which is ugly and confusing from a maintainability standpoint.

Hiring

YMMV here, but in Toronto, hiring an AngularJS developer is pretty damn hard. We've been looking for a while, but without much success (and we even have a dedicated hiring team). For comparison, another discipline where we historically had difficulty finding good candidates was for backend dev positions, and we've been able to hire 5 since the time we've started advertising for the Angular position. (and yes, we're still hiring for both positions and more).

But the bottom line is that, when the time comes to actually expand the team, the number of people with both a strong front-end background (to deal w/ Angular bugs) and the backend engineering chops to follow the AngularJS way (tm) of designing applications turns out to be surprisingly small.

Conclusion

Angular continues to improve its weak areas and gain momentum, but there are still some somewhat big technical issues and quirks that make development challenging. The unique positioning of the framework in the context of specializations within the industry also brings recruiting challenges to the table.

On a separate note, one commenter expressed interest in a post about backbone. Are people interested in analyses of other frameworks as well?