On Thu, Sep 09, 2004 at 09:41:36AM +0200, Jan Nieuwenhuizen wrote: > Lionel Elie Mamane writes: >> write (lambda (x) (accumulate cons nil x)) . This >> non-curryfication is IMHO one of the most irritating "features" of >> Lispy languages. > I'm not familiar with caml like languages, could you explain what it > is you find irritating? Yeah, sure. 1) (One of) the point(s) in using functional languages (for me) is that one can pass around functional values just as "normal" values. Write higher-level functions, combinators, that abstract powerful programming constructs and patterns and make them easy to use, while typing few characters. Joost has shown a few of these "classical" combinators in his "scheme intro". 2) Brevity (taken reasonably) is a positive feature of a language. The feature I'm talking about is the syntax that if f is a function that takes n arguments, then (f a) is a function that takes (n-1) arguments and behaves as (lambda (x_0 ... x_{n-2}) (f a x_0 ... x_{n-2})) . Mathematically, this makes use of the natural isomorphism between A^(B*C) (the functions that take two arguments, the first in B, the second in C, returning something in A) and (A^C)^B (the functions that take an argument in B and return something in A^C, namely a function that takes something in C and returns something in A). Seen from this point of view (the "curryfied" point of view), writing (lambda (x) (f a x)) is actually "just" an unnecessary complicated equivalent of (f a). Just like (lambda (x) (f x)) is ... just f, (lambda (x) (f a x)) is just (f a). (This is called eta-reduction, by the way.) Let's look at an example: let's suppose I want to increment every element of the list l. Without curryfication, I have to write something like (map (lambda (x) (+ 1 x)) l) with curryfication, I would write: (map (+ 1) l) which is much shorter and much more readable. Here you see that actually, curryfication conflicts with a feature of Lispy languages: variable number of arguments. The thing that lets you write (+), (+ 1), (+ 1 2) or (+ 1 2 3 4) and these all have an (integer) value, while in ML (+) is a function (of two arguments), (+ 1) is a function of one argument, (+ 1 2) is an integer and (+ 1 2 3 4) is not correct: It is the same as (3 3 4), i.e. using an integer as a function. Now, I want to increment every element of an element in a list of lists: (map (lambda (x) (map (lambda (x) (+ 1 x)) x)) l) vs (map (map (+ 1 x)) l) For a list of lists of integers, compute the sums of the half of the elements (where +3 is the function that takes three arguments and returns their sum): (map (lambda (x) (fold_left (lambda (x y) (+3 x y)) x)) l) vs (map (fold_left (+3 2) 0) l) This "partial application" of functions to create new functions is actually very common (at least, I tend to make use of it a lot). A lot of "small" functions one wants are an already existing function, with some of its arguments already chosen/bound. Am I making sense now?
<<inline: signature.asc>>