From: Fernando
Subject: Uses of curryed functions
Date: 
Message-ID: <Xe_35.16$7Q3.636@m2newsread.uni2.es>
Hi!

    After learning about curryed function, I couldn't avoid considering a
cool concept but, what for?  Could somepne please show some real world
application of it? O:-)

TIA

From: Hannah Schroeter
Subject: Re: Uses of curryed functions
Date: 
Message-ID: <8iqirt$avu$1@c3po.schlund.de>
Hello!

In article <················@m2newsread.uni2.es>,
Fernando <···@mindless.com> wrote:
>Hi!

>    After learning about curryed function, I couldn't avoid considering a
>cool concept but, what for?  Could somepne please show some real world
>application of it? O:-)

At least it saves writing in some higher order code, e.g.

  let l2 = map ((+) 1) l1 in ...

(Haskell notation). In Scheme, you'd need a definition like this

(define (plus x1) (lambda (x2) (+ x1 x2)))

Then you can

(let
 ((l2 (map (plus 1) l1)))
 ...)

However, then the normal addition would look odder than the normal
Scheme usage, namely
((plus 1) 2) instead of (+ 1 2).

Compilers for languages which often use curried definitions for
multi parameter functions (such as ML, Haskell) usually recognize when
all parameters are given at once and use normal parameter passing
for all the parameters in that case, so curried functions are not
more expensive in normal usage.

Regards, Hannah.
From: Johan Kullstam
Subject: Re: Uses of curryed functions
Date: 
Message-ID: <uu2en7y23.fsf@res.raytheon.com>
"Fernando" <···@mindless.com> writes:

> Hi!
> 
>     After learning about curryed function, I couldn't avoid considering a
> cool concept but, what for?  Could somepne please show some real world
> application of it? O:-)

i think you use it as a lambda shorthand.  it's not that useful in
lisp since lambda is easy.

example

say you have a numerical integration function
(integrate fn a b)
where you compute the integral of the function fn from a to b.  fn
takes one argument.  suppose your function takes two args and you want
the first of them fixed to some value and want to integrate over the
second.

from graham
(defun curry (fn &rest args)
  #'(lambda (&rest args2)
      (apply fn (append args args2))))

now you can do
(integrate (curry two-arg-function arg1) a b)

but this isn't much better than
(integrate #'(lambda (x)
                (two-arg-function arg1 x))
           a b)

curry sure isn't as flexible as lambda since you can't fix arbitrary
arguments to the function, e.g.,
#'(lambda (x) (function-with-3-args a x b))

the whole curry thing seems to come from dylan.  maybe their lambda
construct is awkward?  i don't know enough to say.

-- 
johan kullstam l72t00052
From: Thomas A. Russ
Subject: Re: Uses of curryed functions
Date: 
Message-ID: <ymig0q7ezkx.fsf@sevak.isi.edu>
"Fernando" <···@mindless.com> writes:
> 
>     After learning about curryed function, I couldn't avoid considering a
> cool concept but, what for?  Could somepne please show some real world
> application of it? O:-)

Actually, I can't off the top of my head thing of a real world
application that couldn't also be solved by lexical closures, but I can
give a not too contrived example.

I'll assume you know about how MAPCAR works.  Suppose you wanted 


(defun curry (f x)
  ;; Curries the function f by returning a new function that takes
  ;; one fewer arguments.
  #'(lambda (&rest y) (apply f x y)))

Now suppose that you had a list of numbers and wanted to add 10 to that
list.  You could do it by calling

(mapcar (curry #'+ 10) '(1 2 3 4 5 6))

  =>  (11 12 13 14 15 16)

The number passed in could also be a variable, so you could define a
function like:

(defun add-n (n list)
  (mapcar (curry #'+ n) list))

Of course, this could also be done using lexical closures (which is, I
think, the more common idiom):

(defun add-n-closure (n list)
  (mapcar #'(lambda (x) (+ n x)) list))

The closure method has the advantage that you could choose any of the
variables in the function to bind, rather than just the first.  For
example, if you wanted to divide by a certain number you could write

(defun divide-by-n-closure (n list)
  (mapcar #'(lambda (x) (/ x n)) list))

and get the results you want, whereas you wouldn't be able to do this
particular operation using standard currying operators.

There is also the advantage that the closure form can be compiled during
the code compilation phase, whereas the curried function cannot.  The
curry function creates a new function at run-time, so it is not
available when the source file is compiled.  One solution would be to
specifically invoke the compiler at run-time, using something like:

(defun curry-compiled (f x)
  ;; Curries the function f by returning a new compiled function that takes
  ;; one fewer arguments.
  (compile nil `(lambda (&rest y) (apply ,f ,x y))))

This still means that you do the compilation at run time, but at least
you get a compiled function out of it.  The other solution would be to
do the currying with a macro, but unless the argument value were a
constant, this solution would rely on the ability of the system to use a
lexical closure:

(defmacro curry-macro (f x)
  `#'(lambda (&rest y) (apply ,f ,x y)))

(macroexpand '(curry-macro #'+ 3))
  ==>  #'(LAMBDA (&REST Y) (APPLY #'+ 3 Y))

(macroexpand '(curry-macro #'+ n))
  ==>  #'(LAMBDA (&REST Y) (APPLY #'+ N Y))





-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Barry Margolin
Subject: Re: Uses of curryed functions
Date: 
Message-ID: <IX845.96$E45.2237@burlma1-snr2>
In article <···············@sevak.isi.edu>,
Thomas A. Russ <···@sevak.isi.edu> wrote:
>Actually, I can't off the top of my head thing of a real world
>application that couldn't also be solved by lexical closures, but I can
>give a not too contrived example.

Since currying is just a way for the language to construct the closures
automatically by recognizing when you've used a function with too few
parameters, this is obviously true.  Currying is just syntactic sugar for
closures.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Graham Ward
Subject: Re: Uses of curryed functions
Date: 
Message-ID: <87itv2iymi.fsf@albertine.gorgeous.org>
Barry Margolin <······@genuity.net> writes:

> In article <···············@sevak.isi.edu>,
> Thomas A. Russ <···@sevak.isi.edu> wrote:
> >Actually, I can't off the top of my head thing of a real world
> >application that couldn't also be solved by lexical closures, but I can
> >give a not too contrived example.
> 
> Since currying is just a way for the language to construct the closures
> automatically by recognizing when you've used a function with too few
> parameters, this is obviously true.  Currying is just syntactic sugar for
> closures.


As an exercise in learning CL, I recently wrote a stupid and ugly
macro that would define a function of keyword arguments in such a way
that if you don't provide all the arguments, you get a function of the
leftover ones, like this:


   (defcurry foobar (&key x y) (+ x y))   ; => FOOBAR

   (foobar :x 3 :y 4)                     ; => 7

   (funcall (foobar :x 3) :y 9)           ; => 12


I haven't thought of a use for it yet . . . 

Cheers,



g