[Haskell-cafe] Real World Haskell: confusion

Derek Elkins derek.a.elkins at gmail.com
Tue Jan 13 23:24:26 EST 2009


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?



More information about the Haskell-Cafe mailing list