
On Tue, 2009-01-13 at 19:23 -0500, Anton van Straaten wrote:
Derek Elkins wrote:
No, it means exactly what you said it means. People abuse it to mean the second sense. Those people are wrong and there is already a term for that second sense, namely "partial application." I really wish people would stop conflating these terms*, all it does is create confusion.
+1
* A related annoyance is people who talk about languages "supporting currying and/or partial application." Unless one means that the language supports higher order functions at all by that, it doesn't make any sense. Haskell has no "support" for currying or partial application. The fact that most functions are in curried form in Haskell is merely a convention (with, admittedly strong -social- ramifications.) The only way one could say Haskell "supports" currying is that it has a lightweight notation for nested lambdas.
Compared to most other languages, that lightweight notation makes enough of a difference that it's reasonable to say that Haskell "supports currying and partial application".
E.g., in Haskell:
f x y z = ...
Haskell without the above notation:
f x = \y -> \z -> ...
This would be adequately lightweight for me, especially in a language that was impure.
Javascript, to underscore the point:
function f(x) { return function (y) { return function (z) { ... } } }
This is what my javascript looks like. I guess I could implement some curry functions and write: curry3(function(x,y,z) { ... })
"Standard" Scheme:
(define (f x) (lambda (y) (lambda (z) ...)))
Scheme with a common macro to "support currying":
(define (((f x) y) z) ...)
That's just the function definition side. On the application side, Haskell has a lightweight notation for application in general, i.e. you write "f a b c" instead of e.g. "f(a)(b)(c)" in C-like syntaxes or "(((f a) b) c)" in Lisp-like syntaxes.
Together, these two sugary treats make it quite a bit more convenient and practical to use currying and partial application in Haskell (and ML, etc.), and this translates to *much* more use in practice.
Anton
I consider the notation "f(a)(b)(c)", both lightweight and ideal syntax for C-style languages. You really, really don't want it to look too much like normal application in those languages as the "f(a)" part in the above term can have significant side-effects, and otherwise it's almost as minimal as Haskell* which is the most minimal possible. I will agree that many languages have an extremely verbose syntax for lambda abstraction. A lightweight syntax for lambdas is very handy. A good example of this is Smalltalk's blocks which makes using HOFs for all control structures reasonable. (Smalltalk then messes things up as far as currying is concerned by having a verbose application syntax.) Can't account for poor tastes on the part of language designers, though some are getting hint including Javascript's designers. Examples: C#2.0: delegate(int x) { return delegate (int y) { return x + y; }; } C#3.0: x => y => x+y -- A lighter weight syntax for lambda than even Haskell! JS1.7: function(x) { return function(y) { return x + y } } JS1.8: function(x) function(y) x+y * In many cases, equally minimal: f(x+1)(2*x)(x+y) Javascript or Haskell?