Tuesday, June 11, 2013

Aspect Oriented Programming in JavaScript

You may have heard about AOP recently or about some of the new libraries that are coming out. The first I had heard about it was with Angus Croll's talk on How we learned to stop worrying and love JavaScript, although they just called it advice (and is now being used in Twitter Flight). So just what is Aspect-Oriented, and why do you care?

Aspect Oriented programming is actually a subset of Object Oriented programming. It helps in code re-use where there are cross-cutting concerns that don't fit well in to the single inheritance model. These can be things like logging which you may want to apply to objects throughout your program that don't share a common ancestor that would make sense to add the functionality to.

So what we really need is functionality (called "advice", which is what Angus named his library) and a mechanism to add it to an object (called a "pointcut") and these two things together are called an "aspect". In the speaker deck we are given "before", "after" and "around" as our pointcuts, and our Aspect is actually the function that contains these. It turns out that using functions for describing these aspects are quite useful.

I wrote a plugin for Backbone called Backbone.Advice which we use at work. We've created a file which contains a lot of these mixins that we can now apply across different contsructors. This has allowed us to separate out logic which was repeated in disparate parts of the system, and f you look at the github repo you will see some examples which will do things from automatically listing views to giving you keyboard navigatable lists. Aspects turn out to be very handy.

So now the downsides. Using AOP makes it extremely difficult to debug. You will use functionality across different parts in your system but not necessarily know where it's going to be put when writing. You will also have a fairly ugly callstack, especially if you apply a few different aspects.

So how do we get around this? The trick is to keep the aspects simple and testable. If you have a look at the mixins you can see that often we're making another call to this.mixin(Mixin....); which gives us a sort of inheritance structure. We're also careful about our naming, keeping things consistent across aspects. Also we only allow mixing in on a constructor and not an instance which means we can easily find out what mixins are being used.

Some other AOP javascript libraries you can look in to:

Tuesday, June 4, 2013

Monads in plain JavaScript

So you want to know what these Monads thing is? Douglas Crockford in an interview said that if you understand them you lose the ability to explain them, and then went on to do a Monads & Gonads talk. In the talk he said you don't have to understand category theory or Haskell and I happen to agree, but then he jumps in to some generic monad constructor that may be confusing at first. So what's a monad in plain english?

Simply put it's a wrapper around a value. There are also some laws that it should conform to, but more on that later.

As with any wrapper we need two methods, one to get and one to set the value. These are called "return" and "bind". Let's construct the "Maybe" monad - the easiest monad to get your head around:

var Maybe = function(value) {
  this.value = value;
};

So we have a constructor, monads are something called a "functor" which basically is a "functional object" that allows you to move values between sets. In this case the maybe monad will allow us to use "undefined" in places which expect an actual value and we would see an error otherwise.

So let's look at the return function:

Maybe.prototype.ret = function() {
  return this.value;
};

Nice and easy, it gives us a method to get the value of the monad. Now comes the fun part, bind:

Maybe.prototype.bind = function(fn) {
  if (this.value != null)
    return fn(this.value);
  return this.value;
};

So the bind function runs a given function with the value of the monad. In the case of the maybe monad it just skips running the function if the value doesn't exist - and that's it!

Now we should talk about "lift". you'll see that the bind will return whatever the function returns for the value. Well we want a monad as a return so you should be passing in functions that return a monad - but who wants to do that? instead we'll just create a "lift" function that can take in a function that returns a normal value and changes it to a monad. pretty easy, it'd look something like this:

Maybe.lift = function(fn) {
  return function(val) {
    return new Maybe(fn(val));
  };
};

so now we can do things like have an addOne function:

var addOne = function(val) {
  return val + 1;
};

lift it:

var maybeAddOne = Maybe.lift(addOne);

then you can use it with bind! But what if we have a function that takes two monads? say we want to add two together?

Maybe.lift2 = function(fn) {
  return function(M1, M2) {
    return new Maybe(M1.bind(function(val1) {
      return M2.bind(function(val2) {
        return fn(val1, val2);
      });
    }));
  };
};

This one's a bit more complicated, but basically it just uses closures to get the values from the two monads before running it through the function, and because it's a maybe monad it will just pass back undefined  so we can safely use undefined values without errors. You can try it out like this:

var add = function(a, b) {return a + b;};
m1 = new Maybe(1);
m2 = new Maybe(2);
m3 = new Maybe(undefined);

var liftM2Add = Maybe.lift2(add);

liftM2Add(m1, m2).ret(); //3
liftM2Add(m3, m2).ret(); //undefined
liftM2Add(m1, m3).ret(); //undefined

And that's it. So to recap a monad is just a container. You can pass in a function to operate on it and get a returned value, or ask for it's value. You've probably used monads in the past without knowing (like promises, you just send it a function to run on it's value and it returns back itself - so it's a lifted bind) and perhaps even created some.



Wednesday, May 1, 2013

Logic in templates

Template engines have seen a recent rise in use with the popularization of the MV* model of programming. It's easy to see why, we are no longer writing websites where content is key, but creating dynamic applications where user interaction decides what is on screen. Because of this we don't want to download html from the server every time, instead we want to take our data and put it in a template that we can reuse for the layout. It's an obvious choice and one that works well. However we've started to run in to a bit of a problem, but first a recap on some HTML history:

Event Handlers in HTML

Not so long ago we were writing things like this:

<a href='#' onClick='window.open("http://rhysbrettbowen.com");'>open site</a>

okay, not a good example but that's not the point. The point was that we were littering our HTML with code that only run on an interaction with the element. The issue wasn't the element interaction, it was where we put the actual logic. The issue is that putting actual implementation logic in the HTML gave us a whole other place to hunt for bugs and find where logic was, plus it looked ugly. Sometimes the code you wanted to write had to be more than a few lines long, and things really got bad. It also meant that any change to the implementation logic would have to be changed in the HTML, and changing the HTML may change the behaviour of the page so it meant less people could alter it.

Event Handlers in Scripts

So then we put our event handlers in the scripts. This was great and solved all sorts of problems. It meant that we could get a handle to an element and attach functionality there. This meant we could also change the functionality based on different circumstances. This worked great, while we knew what HTML was on the page. Then we started to get clever and made our pages dynamic.

Event Handlers in Templates


So we started using templates which could have data passed in to them. This meant we had the power to inject data directly in to the DOM before adding it to the page. We also put in functionality in things like data attributes that would declare what functionality an element should have, and all this is a good thing. (Also please note the difference in declaring the functionality, we now declare something on elements but the actual implementation lives in libraries like Knockout or Angular).

Back to the issue at hand

The problem though is that with the ease of using templates we forgot about the bad old days and reintroduced logic in to the template. By logic I mean things like "IF" statements. The issue with IF statements is that they increase code complexity, and they're doing it in the template which is a place that we would like people like designers and other non-professional coders to write. Every time you nest and IF statement you increase the factor of code paths through your code by 2. So if you have 3 IF statements then you suddenly have 2 ^ 3, or 8 different paths your code can take. Because it's logic you should then be writing 8 different tests for your template to get 100% coverage. Do you really want to do that?

So how do we fix it?

The fix is usually quite easy. In most cases you can compute a value and pass it in to the template. This works for things like adding on a class depending on a value. You can use things like rivetsjs to declare your intent in the data attributes in a manner easy enough for a non-professional coder altering the template to understand and use (DSLs like this are great for a while team to learn so they can collaborate together).

In pure OOP there are no IF statements - there is even a website about it. Basically instead of an if statement with two paths you have two different objects. These object share a function name and dependent on which object you call a that function will run. In the case of MV* we've already got objects that come out as DOM, and that is our views (or controls dependent on how you look at it). So all you need to do is write your top view and pass in to it the subview that should be shown in that spot, now dependent on which subview you pass in you will have different things appear in the dom (as they themselves have different templates). The disadvantage to this is no you have a view hierarchy, but if you already have a view manager this should be easy to use. The advantages though are great, you've removed complexity from the templates and what's more you've also broken out the templates in to more logical pieces. Now you can work on those subview templates individually (and I bet they'll increase in complexity over time so you'll be saving yourself a headache).

The other great thing is now there is no logic in the template you shouldn't need to run it any time there is a change in the data. A problem is an if statement may not put some elements in the page, that you'll want to show on the data change, so you would have to re-run the entire template. If you've split out in to a smaller view, you only have to replace the view and the rest of the template can remain untouched. That's a big win not having to re-render DOM and reset all event handlers. Also because you no longer have to re-render the entire DOM you can now use bindings between elements, as those elements won't change.

So just say no to logic in templates.