Functional, TDD JavaScript (influenced by Haskell, Lisp, Erlang...)

Having developed a taste for Functional Programming (FP), I've found that there are many aspects that make building software in a TDD style easier. Functions are the basis of FP, a function that takes arguments and returns values is easy to test. If this function is side effect free (i.e. doesn't effect the program from outside its internal scope; has no infulence on, or effect from, state), you can be confident that that function will always work the way your tests expect.

// SIDE EFFECT FREE
fAddOne = function (num) {
    return (num + 1);
};

test("fAddOne", function () {
    eq(fAddOne(0), 1);
    eq(fAddOne(1), 2);
});

// SIDE EFFECT DEPENDENT
obj = {
    num: 0,
    pAddOne: function () {
        this.num += 1
    }
};

test("pAddOne", function () {
    obj.num = 1;
    obj.pAddOne();
    eq(1, obj.num);
});

In the above examples, fAddOne will work anywhere within the app, pAddOne is side-effect based and needs to be called within the scope of an object with a num property. If a refactor in needed, fAddOne, and its tests, can move arround or change applications. pAddOne has some requirements that unit tests don't describe as easily, refactoring will be a little trickier. In effect pAddOne's tests are testing side effects not functionality.

However, the example oversimplifies the problem. In reality side effects are essential, I/O can't be avoided. In (browser based) JavaScript this is usualy in the from of DOM API interaction. In GB.js I attempt to keep a CYOA/GameBook engine independent of side effects, in the demo, DOM building and events are kept to a minimum and try not to overlap. This is fine for individuals working to their own requirements. Teams have different problems; in JS, side effects are easy and the syntax encourages them, in most cases it's easier to just cave in. It may even get work done faster (at first). But, from a Unit Testing perspective quality drops or, at least, refactoring become trickier.

FP is a tool industry could gain more of value from, as does by adopting its features and principals (closures, currying, recursion etc...). The problem for me is blending Object Oriented (OO) and FP styles with TDD. Refactoring and reuse are important, and when a shortcut is made with OO then quality can suffer.

Another gain with FP can be shorter code, but when using TDD with loosely typed languages (JS, Erlang, Lisp etc...) type checking causes length to creep up. While rewriting some of excersises from "The Little Schemer" (with TDD JS) it became apparent that if you want high confidence in the Unit Tests then a lot of type checking happens. This is why I have a set of type checking functions that I use constantly. So, if I'm typechecking a lot am I just re-inserting the type safty of a strongly typed language?

Looking at other FP languages, Haskell currently satisfys me the most. Sepparating  side effects into Monads (I'm still in the process of learning this concept) and using strong typing (and a compiler) feels like it provides real confidence in quality. In fact, by having to decide types in the function definitions there is no need to have tests to cover type safety. So the extra "boiler plate" (that isn't even required by the compiler) can reduce the overall lines of code typed.

I'm hoping that by delving deeper into Haskell's approach I can get a clearer steer on how to construct functional JavaScript applications.