by Angus Croll

express yourself: rapid function definition

The native JavaScript function indexOf, applied to a String, returns the index of the first occurrence of a specified value. Useful as it is, I often find myself wishing for a variant method that will return the index after the occurrence so that I can pass the result to a slice call and return everything after a given character.

With this in mind, I created a method called express (as in expression, and alsoquick) which returns a new function by applying the expression argument to the result of the old function. Its partly inspired by the Haskell language and by Oliver Steele’s lambda function.

The implementation is deceptively simple but packs a lot of power. The expr argument manipulates a variable r which is a proxy for the return value of the original function. I think its a nice illustration of why eval is not always evil – and how when used judiciously it can actually be a good friend. [Edit 05/12/10: Several readers have pointed out that the r reference could break down if you js minify. I’ve since addressed this issue using a minify-safe evalR function, which will always inject the given variable as “r”, no matter what]

Keep in mind that when there is already an existing function that will perform the required modification, compose might be a better option (especially if you’re skittish about eval). What do you think?

As with any technique, its easy to overdo it. I wouldn’t necessarily recommend using global express in production code (its perfectly robust but your team might not appreciate the unfamiliar syntax or reliance on eval). However it does illustrate the beauty of the functional approach, moreover it’s an excellent aid in debugging, testing and experimentation on the console.

Now lets go back to the indexAfter method we defined at the beginning. Here’s a nifty example that combines compose, curry and express to define a function that will extract the domain part of an email address.

Of course, some syntactic sugar would fix that extra syntactic burden (though not the unnecessary function calls) and Clojure actually has some syntactic sugar that handles this type of situation. If I were to bring that syntactic sugar in to the JS world, it might look like this:

map(#( %.someMethod() ),
____list);

Maybe its just me, but I also think that (in general) function calls look cleaner than method calls.

I like this slightly modified version of compose that is a normal function rather than a Function.prototype method (and also takes variadic number of functions to compose):

Nick, Yeah I knew that would be controversial. I thought long and hard before augmenting Function the first time – then after that I felt I had to keep doing it for consistency. Namespace pollution issues aside I think it looks clean (I’m allergic to too many arguments) but its very much a matter of taste.

I’m planning an upcoming post(s) on compose and curry on steroids including chaining/muti-function compose directives and partial function (i.e. curry but with pre-assign any argument not just first n).

However, I don’t like using undefined as a placeholder (too verbose, looks funky, might actually want to pass undefined in), and a lot of other people don’t either if you read the comments on his post. I would use _ as the placeholder, but since underscore.js came out (http://documentcloud.github.com/underscore/ which you would like, if you aren’t familiar already) _ is kind of a no deal. Ended up with three underscores, ___, and I think it looks great. By binding the placeholder to an empty object, you know that you can never “accidentally” pass an object that can be compared to ___ and have the comparison return true, which is a real issue when using undefined as the placeholder.

Good point about minifier side-effects. As I said in the post , I would not necessarily recommend this approach for production code – but I wanted to try to push the boundaries of JavaScript as a more expressive, functional language – and its a useful device for trying things out in the console, and debugging

(btw Oliver Steele’s lambda function does something similar but without requiring eval)

I recently did something similar as an extension to the Underscore library, where any function that takes an iterator function can be replaced by a string (or regex) expression. It doesn’t use ‘eval’ but ‘new Function()’ which also solves the minify problem. See: http://github.com/moos/_xiterator