1

Currying functions can be usefull:

function tag(name, value) {  
    return '<' + name + '>' + value + '</' + name + '>';
}

var strong = tag.bind(undefined, "strong");
strong("text"); // <strong>text</strong>

Now imagine we have to use another function with wrong order of parameters

function otherTag(value, name) {  
    return '<' + name + '>' + value + '</' + name + '>';
}

How to use bind function to get the same result - create strong tag using otherTag function.

How to curry this function using bind only?


I'm not interested in solution based on wrapping the otherTag function like this:

wrapOtherTag(name, value) {
    return otherTag(value, name);
}

What I want to know if it is possible to pass arguments to bind to tell the order of arguments we want to curry.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
opengrid
  • 1,942
  • 4
  • 16
  • 25
  • Nope. Arguments are bound in the order you pass them. You'd have to implement your own solution. – Felix Kling Jan 15 '13 at 20:28
  • 2
    @opengrid. You may get more interest if you detail a situation where this might be useful. – Paul Fleming Jan 15 '13 at 20:30
  • 2
    @opengrid. P.S. Are you sure `currying` is the correct term for what you're asking? – Paul Fleming Jan 15 '13 at 20:30
  • 1
    I don't understand the point of this. You want to reverse the order of arguments, but you want bind to magically know what order you want them to be in? Why not use an object: `{name:name, value:value}` in that case? –  Jan 15 '13 at 20:33
  • 1
    The Functional.js library has a function that lets you do this, though it's mostly useful as an academic example. – Pointy Jan 15 '13 at 20:37
  • @flem: Yes it is :-) http://stackoverflow.com/a/36321 – gen_Eric Jan 15 '13 at 20:45
  • I like Functional.js solution. so bind is only for simple cases. – opengrid Jan 15 '13 at 21:33
  • [This](http://stackoverflow.com/questions/4394747/javascript-curry-function?rq=1) shows a way to do currying in js. – Lee Meador Jan 15 '13 at 23:10
  • @LeeMeador I think bind is more concise way to curry a function unless you want do things that only rcurry or partial can do. – opengrid Jan 16 '13 at 00:53
  • @opengrid, `.bind` is *based* on that implementation of currying. It's native, now, for modern browsers, but that is how shims and libraries *make* their `.bind` functions to begin with. The point of `.binding` is to return the exact-same function, in the exact-same order, with an encapsulated value for `this`. Currying from there is a matter of popping arguments off the stack and returning half-created functions which use cached versions of those arguments. You can build complex versions of that, you can build a function which inverts the order, you can use configuration objects, not bind. – Norguard Jan 17 '13 at 16:21

2 Answers2

2

Write a function to reverse argument order:

function swap(fn) {
    return function(a, b) {
        return fn(b, a); 
    };
}

Now just call

swap(otherTag).bind(0, "strong");
1

You can write your own function to accomplish this.

// Uncurry `this` in `slice`.
var slice = Function.prototype.call.bind(Array.prototype.slice);

function curry(fn, arg, index) {
    return function curried(/* ...args */) {
        var args = slice(arguments);
        args.splice(index, 0, arg);
        return fn.apply(this, args);
    };
}

var strong = curry(tag, "strong", 0);
strong("text"); // <strong>text</strong>

var otherStrong = curry(otherTag, "strong", 1);
otherStrong("text"); // <strong>text</strong>
Nathan Wall
  • 10,530
  • 4
  • 24
  • 47