Skip to content

Instantly share code, notes, and snippets.

@AntJanus
Last active August 29, 2015 14:03
Show Gist options
  • Save AntJanus/3070178a2594ad301b14 to your computer and use it in GitHub Desktop.
Save AntJanus/3070178a2594ad301b14 to your computer and use it in GitHub Desktop.
Using currying to build an assertion library
var assert = function(evaluateFn, variadic) {
return function() {
var args = [].slice.call(arguments, 0, arguments.length - 1);
var msg = arguments[arguments.length - 1];
if(variadic) {
var evaluation = evaluateFn(args);
} else {
var evaluation = evaluateFn(args[0], args[1]);
}
if(evaluation === true ) { return true; }
else { return msg; }
}
}
var assertAllEqual = assert(function(els) {
for(i in els) {
if(els[i] != els[0]) { return false;}
}
return true;
}, true);
var assertEquals = assert(function(a, b) { return a == b; });
var assertGreaterThan = assert(function(a, b) { return a > b});
//elsewhere
var d = 80;
var f = 90;
var c = 30;
assertAllEqual(d, f, 'D should equal F'); //message shows up
assertAllEqual(d, f, c, 'All variables should be equal'); //message shows up
assertAllEqual(d, 80, 80, 'All should equal'); //true
assertEquals(d, f, 'D should equal F'); //message shows up
assertEquals(f, 90, 'F should equal 90'); //true
assertGreaterThan(f, d, 'F is greater than D');
@AntJanus
Copy link
Author

@lelandrichardson , out of curiosity (and after reading http://tech.pro/tutorial/2011/functional-javascript-part-4-function-currying), how would you structure the top assert function to allow the subsequent curried functions to accept an arbitrary number of elements; however, treating the last variable always as an assertion message?

For instance:

var assertEquals = assert(function(???) {  return a == b && b == c && c == ....});
//to yield
assertEquals(a,b,c,d,e,f,g,h, 'All of these should equal!');
assertEquals(a, b, c, 'This should work too');

without using arrays (eg. assertEquals([a,b,c,d], 'Message'))

@lelandrichardson
Copy link

Hey Antonin,

What you are looking for is probably more closely a variadic function helper. Curried functions rely on the total number of arguments being constant (so you can know when you are "done").

Alternatively, you could use a simple higher-ordered function coupled with the arguments variable.

Option 1: Variadic functions:

var assertEquals = function () {
    var args = [].slice.call(arguments, 0, arguments.length - 1);
    var msg = arguments[arguments.length - 1];

    // ... use msg, args variables
};

// usage
assertEquals(a, b, c, d, 'Error!');

Most variadic functions / helpers work with the variable number of arguments being LAST not FIRST, but you can do either just as easily.

Option 2: Higher order function

var assertEquals = function () {
    var args = [].slice.call(arguments);
    return function (msg) {

        // use msg, args variables
    };
};

// usage
assertEquals(a, b, c, d)('Error!');

@AntJanus
Copy link
Author

Ah! Awesome, I reworked the function and got it working :)

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment