Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Four Cs of JavaScript (dailyjs.com)
29 points by wgj on Feb 7, 2010 | hide | past | favorite | 4 comments


The third one should be called chaining rather than cascade and the fourth one 'curry' should be dropped (it is not really all that useful) the solo example mentioned is probably the only one in a public library.


The most egregious fault of the fourth point is that it is not actually currying in anything but the colloquial sense. It is correctly called partial application.

In comparison if you were to curry the function

   function foo(a, b, c) { return [a, b, c]; }
you would get something approximating

   function foo(a) { 
       return function (b) { 
           return function (c) { 
               return [a, b, c]; 
           }; 
       }; 
   }
This new form is trivially partially applicable, eg:

    foo(1); // returns a function accepting b
if you wished to call it with all the arguments you would need the rather ugly

    foo(1)(2)(3); // returns [1, 2, 3]
The two are regularly confused. I'm not even sure you could automatically curry a function in JS because of the very flexible varargs support.

In contrast with this, partial application is often very useful, its easily written, and fairly common if not in the all the popular libraries.


Let S=strings,s=string,t=string, where s=s_1.t.s_2.t.....t.s_n

Let split be a function from S*S->S[] such that split(t,s)={s_1,s_2,...,s_n}. For example split(" ","a b c")=["a","b","c"]

Let split_c1=curry(split). Then split_c1 is a function from S->(S->S[]) such that:

split_1(t) is a function from S->S[] such that split_1(t)(s)=[s_1,s_2,...,s_n].

For example, split_c1(" ") is the function that given a string s splits s on the separator " ". Let splitOnSpaces=split_c1(" ") be this function. Then splitOnSpaces("a b c")=["a","b","c"]

The example in the link is

String.prototype.splitOnSpaces = String.prototype.split.curry(" ");

"foo bar baz thud".splitOnSpaces(); // ["foo", "bar", "baz", "thud"]

The javascript curry function takes a function (here split), and a parameter to that function (here " "). It then curries the function. It doesn't return this curried function directly, but immediately applies it to the parameter it was passed to give a new function, which it returns. In the notation above it's returning split_c1(" "), in other words splitOnSpaces.

Executing a function on an instance of a class applies that function to the class. So "a b c".splitOnSpaces() means splitOnSpaces("a b c"). As we saw above this returns ["a","b","c"].

Currying and partial application are very close, hence the confusion. The javascript curry function not only curries but also applies a parameter and returns the resulting function. So I think it's not entirely fair to say it's not currying anything. It can be seen as currying and then passing a parameter to the curried function.

Am I right here? This is mainly based off currying as explained by wikipedia...


The prototype source[1] has the answer, and it does not curry the function. In fact it does not even perform real partial application. It just returns a closure that has references to the original function and the argument(s) you asked it to partially apply. When you call the resulting function it merges the new arguments and calls the original function.

[1] http://github.com/sstephenson/prototype/blob/master/src/lang...

Conceptually it's the same as partial application so most of us would overlook that detail, but it is nowhere near currying. See Haskell if you're interested in these concepts.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: