Theta Waves

Break it, Fix it, Repeat.

Bind vs Curry in JS

As of ECMAScript 1.8.5 javascript implemented the bind() function which can also be found in underscore.js as _.bind(). It allows you to bind a function to a this context as well as bind some predefined arguments. Binding predefined arguments in other functional languages like haskell is known as partial function application and goes by the name of currying.

So whats wrong with bind

The problem with bind is that it has two majorly different use cases, context binding and partial function application. This makes reading code that contains bind() calls in it slightly less concise because just reading the name of the function isn’t enought to tell you what the intended goal of the operation is. It can be used for context binding, partial function application or both.

Sounds like a swiss army knife

Swiss army knife functions are something to be weary of when you intend to write concise and readable code. By looking at the funciton protocol for bind it seems like it was originally intended to be used just for context bind and partial function application was almost an afterthought. For this reason, when you use the bind function strictly for context binding not only does it create intuitive code but also cleaner looking code. You’ll see what i mean when you try to use the bind function strictly for currying as it creates the opposite effect.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* `bind` used strictly for context binding
*/
var base = {
greeting: "Welcome",
name: "Joseph",
greeter: function() {
console.log(this.greeting + " " + this.name);
}
}
var asyncOp = function(callback) {
// do async work then invoke the callback
callback();
}
// nice clean and intuitive use of `bind`
ascynOp(_.bind(base.greeter, base));
/**
* `bind` used strictly for currying
*/
var lines = function(text) { return text.split("\n"); },
unlines = function(lines) { return lines.join("\n"); },
drop = function(count, arr) { return arr.slice(count); };
var stripFirstLine = _.compose(
unlines,
_.bind(drop, undefined, 1), // note the `undefined`
lines
);
var text = "line1\nline2\nline3";
console.log(stripFirstLine(text));

We can do better then that

So the undefined parameter in the previous example is a staple wtf code sighting in javascript. We can prevent having to pass undefined while making our code more concise by using a custom implementation of curry. You can see how the method we composed becomes more concise in the following example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Custom curry implementation. There are probably cleaner ways to
* implement `curry()` but this is just the one i use and it works
* for me.
*/
// i like to create it as an underscore mixin
_.mixin({
curry: function(func) {
var applied = Array.prototype.slice.call(arguments, 1);
return function() {
var args = applied.concat(Array.prototype.slice.call(arguments));
return func.apply(this, args);
};
}
});
var lines = function(text) { return text.split("\n"); },
unlines = function(lines) { return lines.join("\n"); },
drop = function(count, arr) { return arr.slice(count); };
var stripFirstLine = _.compose(unlines, _.curry(drop, 1), lines);

Conclusion

  • Use bind strictly to bind functions to contexts
  • Use an implementation of curry instead of bind to create partially applied functions.

The Pass Pattern

Javascript is a programming language that has most of the killer functional programming features you can possibly bake into a C syntax styled language with a hint of prototypical inheritance from the self programming language. This presents you with an interesting multi-paradigm programming environment that through better or worse practices can let you choose which style to program in.

When i write javascript my inner geek gets all giddy because it’s always the perfect excuse for me to exercise functional programming practices in a widely accepted mainstream language. I love functional programming so much in javascript that the library i get the most mileage out of by a landslide is underscore.js, a functional programming library for javascript. Even if you exclude the fact that i use underscore.js in both client side javascript and server side in node.js, it still remains the library that i use the most independently in each environment.

Patterns and abstraction

In functional programming whenever you find yourself typing a similar code pattern multiple times you should consider abstracting it. This is actually true with most programming languages but something of a religious practice in functional programming. However, functional programming languages like javascript have the advantage of having high order functions and lexical closures allowing you to abstract certain patterns better and more concisely then is possible in non functional languages.

Error handling in node.js

As an awesomely consistent and well implemented set of APIs, all API calls in node.js that perform any kind of IO take a function callback to run on IO completion. This is a very fundamental practice at the core of the node.js asynchronous evented model. A familiar site to anyone familiar with node is the pattern of arguments that are passed to the callback. Typically, asynchronous callbacks will take one or two arguments, (error) and (error, value) . The most important part for this article being that error is always the first argument passed to the callback.

The error passed as the first argument to any aysnchronous callback is representative of any errors that might have occurred during the asynchronous operation. Error will be false if no error was raised and non false otherwise. In node.js you often have nested aysnchronous requests and a common approach to error handling is to pass the errors back up the event chain to be handled by a layer knowing what to do with it. This is demonstrated in the bellow pseudo code js example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var express = require("express"),
redis = require("redis").createClient(),
app = express.createServer();
functon getLatestNews(next) {
redis.lrange("news", 0, 25, function(error, value) {
if (error) {
next("failed fetching news");
} else {
next(false, value);
}
});
}
app.get("/", function(req, res){
getLatestNews(function(error, news) {
if (error) {
globalErrorHandler(error);
} else {
res.send(news);
}
});
});
app.listen(80);

There it is the error passing pattern. If you write node.js code you can probably find this pattern throughout your code base. If you can’t it means you’re probably not handling errors which is a big no go.

The pattern can be written a couple different ways

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* strictly nested approach
*/
if (error) {
// pass failure
next(error);
} else {
// pass success
next(false);
}
/**
* refactored to avoid deeply nested code
*/
if (error) {
// pass failure and return
next(error);
return;
}
// do work
// pass success
next(false);

So the money making question is how do we factor out this repetitive pattern being the ace functional programmers that we like to think that we are?

Heres the solution i came up with, i call it the pass pattern. I call it the pass pattern, but really it’s more of an abstraction.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var express = require("express"),
redis = require("redis").createClient(),
app = express.createServer();
function pass(next, after) {
return function(error, value) {
if (error) {
after(error, value);
} else {
next(value);
}
};
}
functon getLatestNews(next) {
redis.lrange("news", 0, 25, pass(function(value) {
next(false, value);
}, next));
}
app.get("/", function(req, res){
getLatestNews(pass(function(news) {
res.send(news);
}, globalErrorHandler));
});
app.listen(80);

So this requires you to setup a function called pass which acts as a closure generator for augmenting the asynchronous callback. The error checking gets dropped from the asynchronous callback, yet the error checking still takes place. The asynchronous callback itself is only ran when no error is present and as a byproduct, we can safely drop the error argument from the first argument of the callback. Just as important, the next callback is automatically forwarded or “passed” the error if one is present.

The above example of pass is just introductory code. The full version of the pass abstraction i use in my code is as follows.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Yeah i use underscore.js so much i add it as a mixin to underscore
_.mixin({
pass: function(next, after, customError, context) {
return function(error) {
var args = Array.prototype.slice.call(arguments, 1);
if (error) {
args.unshift(customError || error);
after.apply(context, args);
} else {
next.apply(context, args);
}
}
}
});

This version allows me to override error messages so if i get back a DB failure error from the database while calling it from the registration form i can override the message with something more meaningful to the user that will get passed along instead. My version also allows context binding so i can avoid some var self = this; annoyances.

Recomended Reading

Parallel Tests.

Some people know them as A/B tests and i think thats really a shame. The name A/B testing implies your intent is to use the parallel testing suite of your choice to gather performance analytics usually on content based differences and variances in the UI. There is a huge value add to using A/B testing just for collecting performance analytics so i’m not claiming that it’s a misuse of parallel test suite implementations. However, the value value adds with parallel testing doesn’t just end with performance testing as it can be used to enhance your product release process, your QA process and even your development process.

Improving the release process

I’ve worked on web products where we’ve done production code releases at midnight once a week and on ones that have one or more releases a day during peak hours. Depending on your past experiences you may think that releasing during peak hours that often is just asking for the fail whale to strike on a daily basis. However, my experience with both was that the midnight releases during hours of really light load where the most chaotic and error prone by an order of magnitude. So coming from that background wouldn’t releasing every day during peak hours be one of the most counter intuitive things ever?

There are no silver bullets and the best way to slay a beast is with lots of lead bullets. I can talk about the value of hiring competent developers, using continuous integration and various release strategies to improve the release process. However, the lead bullet of this blog post is parallel testing.

When you’re developing a new feature you can start it off by wrapping both the new and old implementation in a parallel test and setting the exposure of the old implementation to 100% with the new implementation set to 0% with a manual override on your test user id so that your test account will be presented with the functionality of the new implementation. This new feature can then be committed up the chain and even to prod with the same 100% to 0% test ratio and public facing end users will not have access to the new feature. At this point the only people with access to the new feature would be typically developers, Q/A and various business owners inside the company all of which would be able to test the new functionality in a production environment.

Once the new functionality has been pushed to production, sufficiently tested internally and vetted by all product owners. The release of the product is simply a toggle of the percentage in the parallel test suite from 100% old 0% new to 0% old 100% new. The concurrent test wrapper can even be left in place for undefined amounts of time and you can roll it back and push it back out all from a GUI/WebUI.

Improving the Q/A process

The Q/A process at the places i’ve worked at is always tightly coupled with the release process so i’ve already inherently discussed some of the benefits on how parallel test suites can be used to improve the Q/A process by talking about how it can be used to improve the release process. IE: being able to test new features in production in a manner not publicly visible to users is a huge improvement to the Q/A process alone if you couldn’t already do that before.

Another way parallel tests can be used to improve the Q/A process is they allow you to do selective releases. It’s not uncommon for certain sites to have select users who are highly active, vocal or are just in good contact with the business. You can do selective releases where only employees and those selected users will get initial “exclusive” test access to the feature before it gets released with 100% exposure. This is an easy and almost free way of crowd-sourcing a part of your Q/A department to users you can trust and have past relationships with.

Improve the development process

It first occurred to me that parallel tests can be used to improve the development process when i encountered an article by John Carmack about parallel implementations. Basically whenever he wants to test an alternative implementation of a feature, instead of refactoring the old implementation in place or scrapping it he wraps the old and the new implementation in parallel tests that he can toggle in real time from a console.

This is great for if you want to run benchmarks against alternate implementations because theres a minimal impact on the rest of the code and if the new implementation turns out to be worse you can simply throw out the concurrent test and restore the original implementation as it was without having to dig through branches, tags or commits in version control.

TL;DR

  • Parallel tests for releases
    • Enable/Disable features from a control panel instead of only source control
    • Incremental releases - bucket testing
  • Parallel tests for Q/A
    • Selective releases - crowd sourcing Q/A
    • Private beta tests in production before public release
  • Parallel test for the development environment
    • Enables you to develop alternative implementations and test them back and foward with a toggle

See Also

Initial Blog Entry

Just checking this out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var createNinja = function()
{
var idk = 8055;
var secret = function()
{
return idk *= 1337;
};
return {
watchANinjaGetDown: function()
{
if (console.log) console.log("go ninja go ninja go!");
return secret();
}
};
};