Function Transformation

Modern JavaScript is firmly on the side of magic. Why write a hundred-line set
of meticulous loops when you can write a ten-line filter chain? Why invoke a
factory object dozens of times when you can write a map function? And if you
want your application’s behavior to change from moment to moment, why use
explicit states, or a Strategy pattern, or reference a global flag, when you can
just swap out the functions themselves?

And why swap functions yourself? Let the functions do that for you. Wind them
up. Let them run.

(From here on, I’ll be using JavaScript instead of ActionScript in my examples,
but the concepts are 100% identical. If you use
underscore.as, you can use
very similar code in ActionScript 3. jQuery needs no
introduction.)

Dry-Aged Handcrafted Vintage Content

This article was written in spring 2012, but every word still holds true, and
it applies to JavaScript with very minimal mental translation.

Laborious Authentication

You’ve seen code like this a million times – and in my opinion, that’s 999,999
times too many.

This code is pretty straightforward. First we locate DOM elements using jQuery,
using the leading $ to indicate that they should only hold jQuery-wrapped
elements. Hungarian notation? Guilty, but at least it’s
the good kind.
Our DOM objects located, we define addComment to show the comment form if
possible, and the login form if necessary; and finally, we arrange for the login
form to call addComment again on a successful login.

If you have only one action on your site which requires a login, this kind of
structure is perfectly reasonable. Once you have two, however, you find yourself
copying your login form everywhere, and giving it a different success handler
each time, so it can resume a different user action. You can generate the login
form by cloning a hidden DOM element, but a more insidious problem remains: your
addComment function has to understand the concept of authentication. Any
other function that requires authentication also has to understand the
concept. You will be writing if (authenticated) until the day you die or your
app becomes obsolete—whichever comes first.

(Remember, it’s bad when people never use your app. It’s terrible when they never
stop. Written any good IE6 workarounds lately?)

Sorcerous Authentication

How do we take authentication out of our functions and put it all in one place?
Short answer: sorcery. If you’ve been paying attention to my constant campaign
for passing functions as values, you might immediately think of something like
this:

And this is definitely much closer to something I’d want to use. All our login
handling code moves to a separate function, authenticate, which is not
connected to commenting at all. authenticate can do its work and then execute
the callback to resume the workflow. But your addComment function still
includes the knowledge that the user must be authenticated. Imagine that in some
contexts, you allow anonymous comments, but in others, you don’t: now you have
to write two functions (bad), or include logic in the function to decide whether
a login is required (far worse).

Instead, let’s put the authentication requirement where it’s most relevant: in
the code which defines the behavior of the page itself. addComment can remain
pleasantly generic, while this specific button prompts anonymous users for their
credentials.

The magical line here is foo.click(requireLogin(addComment));. requireLogin
creates a function which displays the login form if necessary, and handles its
success event by executing addComment. If no login is necessary, the
function returned from requireLogin calls addComment immediately. In other
words, the anonymous function which handles the login is wrapped around the
function which handles comments; so this type of function is called a “wrapper.”
You could also say that the login functionality is a “decoration” which can be
applied to any function; so a function like requireLogin is called a
“decorator.”

In a more general sense, addComment goes in, and what comes back is something
that can be used exactly the same way… but which has extra powers.
requireLogin is the gamma-ray chamber. addComment is Bruce Banner. We just
took a function and changed it, while still using it in the same code. If you
know object-oriented programming, the concept
may sound familiar.
Polymorphism: it’s not just for subclasses anymore!

Tinker Toys

That example showed how to prevent the default functionality until a condition
is met, but we can also use decorators to augment a method—to make it do
more than it did before. Our weapon is _.compose, an underscore.js method
which transforms a list of functions into a single one which combines all the
functions into a single pipeline.

In this example, composed is a function which runs baz, then bar, then
foo, passing the output of each function as input to the next. The output of
baz is “baz”; bar places “bar” in front of it to make “barbaz”; and so on.
(message || "") returns the empty string if message is null or false. We’re
accustomed to reading from left to right, so this may feel strange, but once
you’re accustomed to it, _.compose is a powerful tool. Here’s a more practical
example: the “insert” and “delete” buttons add blocks of random text, while
“bold” and “italic” act as modifiers.

The easiest way to understand this example is to focus on the buildElement
function; or rather, the function which is assigned to the buildElement
variable. At first, we assign it buildRandomText; but clicking the “bold” or
“italic” buttons alters that assignment. Click “bold”, and the makeBold
function is added to the currentDecorators array. Click again, and the
function is removed. The underscore.js method _.without makes it easy to
remove a known value from an array; and the mapping between HTML attributes and
method names in a namespace may be brittle, but it’s also extremely convenient.
Pick your poison. And once currentDecorators has some content, _.compose
comes into play.

If “bold” is selected and “italic” is not, currentDecorators only contains makeBold.
Let us revisit the definition of that function:

The function accepts a jQuery element, and returns it after adding the “bold”
class. Simple as that; but more complicated decorators are easy to imagine. In
this case, the decorator is earning its name: it literally applies decorations
to a UI element. An element goes in; an element which should have the same use
case comes out. Remember, decorated functions are meant to be drop-in
replacements for their originals.

_.compose(makeBold, buildRandomText) creates and returns a function which
could otherwise be expressed as makeBold(buildRandomText())… and now perhaps
you see why the arguments to _.compose are written left to right. Add italic,
and you’ll get a function which has the same effect as
makeItalic(makeBold(buildRandomText())). The rightmost function just has to
return a value; each other function has to accept the value returned from the
next one.

A side note: Function.apply

Sadly, _.compose takes variable arguments, not an array of methods, so we have
to use Function.apply before it will operate on our currentDecorators array.
Functions are objects; they can have methods. Function.apply executes the
function within a given context (null is sufficient here), and passes it each
array element as an argument. To put it another way, any function you can call
like this:

Real-World Closures

I know you’re champing at the bit to go write code with like a zillion closures,
but you know deep in your heart that it’s all just showboating. You don’t have
to use this stuff to get real work done, right? And if you do, it won’t save you
much time over just writing some loops and storing some variables in a plain and
simple data structure. You may be right! But that didn’t stop us at
Paperless Post from using closures as part of
our upcoming undo/redo system.