9

Reading through the Wikipedia article on First-Class functions, there is a nice table of language support for various aspects of functional programming: http://en.wikipedia.org/wiki/First-class_function#Language_support

JavaScript is listed as not having partial function application. However, there are techniques for creating a function that returns a function that with some of the parameters stored in a closure, ie:

var add = function(a, b){
    return a + b;
},
apply = function(fn, a){
    return function(b){ 
        return fn(a, b); 
    }
},
addFive = apply(add, 5);

console.log(addFive(2)); // prints 7

Is this not partial function application? If not, could someone please provide an example of partial function application in another language and explain how it is different?

Thanks!

Jason Suárez
  • 2,445
  • 3
  • 18
  • 20

4 Answers4

8
var func1 = function(a, b) {
  return a + b;
}

var func2 = func1.bind(undefined, 3);

func2(1); // 4
func2(2); // 5
func2(3); // 6

check docs at developer.mozilla.org

Andre
  • 538
  • 4
  • 9
6

The concept you should look up to understand this is called currying (after Haskell B. Curry). There is an isomorphism between functions of n+1 parameters and a function with one parameter returning a function with n parameters. If you apply this recursivly you can write a function of any number of parameters as a function to function to functions.

This is why functions in functional languages are usually typed as X -> Y -> Z meaning, this is a function which takes a X and returns a function taking a Y returning a Z. This signature also means you can just supply a X and the function will return a function itself.

In Javascript a function of two parameters will have the signature X * Y -> Z meaning it is a function taking a pair of X * Y and returns a Z. However you cannot supply half a pair.

There are two ways out of this:

  • Always manually curry your function. Your add function could be written as:

    var curryadd = function(a){
        return function(b){ return a + b; }
    };
    

With this you now have a function which has the actual signatur Int -> Int -> Int which is needed for partial function application. However you also have to make sure to call this function as curryadd(5)(10) which is unnatural to do.

  • Supply higher order functions, which curry your functions. In your case the apply does two things, it curries your add function and binds the parameter. This can be divided in two parts:

    var curry = function(fn) {
        return function(a){ return function(b){ return fn(a,b); } }
    };
    

This will actually implement the isomorphism between functions with pairs as arguments and functions which return functions. There also is a way to write uncurry which does the same thing backwards.

Because you have to do all this manually and there is no direct language support, javascript is said not to have partial function application (which does not say you can't add it to the language).

LiKao
  • 10,408
  • 6
  • 53
  • 91
  • I think you forgot some `return` statements in your inner functions. – ThiefMaster Mar 22 '12 at 07:39
  • @ThiefMaster: Yes, I noticed that later, but did not have internet connectivity to change it. I guess you sometimes just forget them, if you are used to much to functional languages, which do not need them. – LiKao Mar 22 '12 at 15:18
5

What you show is an example of higher order functions, functions that take functions as arguments and/or return functions.

Partial application is something different. Here a Haskell example:

add     :: Int -> Int -> Int
add x y = x + y

addOne = add 1

add is a function that takes two Int and returns an Int, denoted as Int -> Int -> Int. If you're unfamiliar with the syntax, in Javascript this would roughly look like this:

/**
 * @param int x
 * @param int y
 * @return int
 */
function add(x, y) {
    return x + y;
}

add 1 calls this function with only one parameter, which returns a new function that takes one Int and returns an Int (Int -> Int). The add function was not explicitly designed to be a higher order function, it was simply partially applied.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Forgive me, I'm not familiar with Haskell syntax. Is the function signature for `add` saying "`add` takes two Ints and returns one Int"? Is this to say that invoking a function that takes 2 parameters with only 1 implicitly returns the partially applied function? – Jason Suárez Mar 22 '12 at 07:19
  • Translated to Javascript. Yes, in simple terms, `Int -> Int -> Int` means it takes two `Int` and returns one. Maybe more correct though, it will transform one `Int` and another `Int` into another `Int`. Real Haskellers will still have a problem with my terminology I suppose, but for the layman this should do. :o) – deceze Mar 22 '12 at 07:23
  • @Thief Sort of, but it's not really "`add` acting like that". It's deeply ingrained in how Haskell evaluates things and cannot really be reproduced in Javascript. – deceze Mar 22 '12 at 07:26
  • So does the term "partial function application" mean the language feature that allows any function to have that characteristic? How does arity work, then? Are parameters applied strictly left-to-right? – Jason Suárez Mar 22 '12 at 07:31
  • @deceze: of course this can be reproduced. It is quite possible to manually curry your functions, even in Javascript. However this will mean writing and using your functions becomes very unnatural. See my answer below. – LiKao Mar 22 '12 at 07:34
  • @LiKao I guess you're right to some degree. You can't reduce the `+` operator to an infix function for example. That puts a damper on currying, since you cannot write `x + y` and have it act as a partially applicable function. You'd have to write everything as a higher-order function or not at all, no such niceties as the language doing it for you due to the fact that everything is a function to begin with. That's nitpicking though. I upvoted your answer, nice explanation. :) – deceze Mar 22 '12 at 07:41
  • @Jason The language feature that allows this is that *everything* in Haskell is a function. Even `+` is a function, which should actually be used like `+ x y`; Haskell just has some syntactical sugar that allows infix notation. That's coupled with the fact that basically every operation returns a function which is applied to other functions. Javascript has separate concepts for statements, operators etc, which puts a damper on how far you can reduce things to functions which can be applied to other functions. – deceze Mar 22 '12 at 07:45
  • @deceze: Yes, being able to curry your operators as well as normal functions is definitely a nice thing. Especially once you start to use a lot of second order functions, such as `map` or `zip`. – LiKao Mar 22 '12 at 15:21
1

As noted in the other answers, what you describe is currying; it is a form of partial application, as you identify.

However, if what you want is just partial application, you can use underscore.js, which adds a lot functional programming utilities: http://documentcloud.github.com/underscore/

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • Thanks for the additional answer. I use underscore, and quite a bit of functional programming techniques, in my JavaScript programming. I was just seeking clarification of what was meant by "partial function application" in the Wikipedia article. I see now that it's a matter of native language support versus having to implement it via higher-order functions. – Jason Suárez Mar 22 '12 at 18:53