Page 1 of 1
Wishlist Item: Improve curry
Posted: Wed May 23, 2007 2:56 am
by rickyboy
When I saw recently that Lutz had added
curry as a new intrinsic procedure, I thought "way cool!" (I still think that, BTW.)
But apparently, you can't curry a function using more than one (curry) argument:
Code: Select all
> (define (f x y z) (* x (+ y z)))
> (define f-2-3 (curry f 2 3))
> (f-2-3 4)
value expected in function + : z
called from user defined function f
called from user defined function f-2-3
However, you can define, as a macro, your own curry functor which fixes this (you've seen this before, e.g. from John Small):
Code: Select all
(define-macro (currie f)
(letex ($f (eval f)
$cargs (map eval (args)))
(lambda () (apply $f (append (quote $cargs) (args))))))
> (define f-2-3 (curry f 2 3))
> (f-2-3 4)
14
So, I'd like for Lutz to consider changing the intrinsic
curry to handle this situation. Then I can get rid of
currie! :-)
Posted: Wed May 23, 2007 12:19 pm
by Jeff
I second this.
Posted: Wed May 23, 2007 4:43 pm
by Lutz
Originally 'curry' was coded like Rick's currie, but for efficiency reasons I went to the simpler curry for only two functions arguments. The current curry has only the lambda overhead:
Code: Select all
(curry func arg) => (lambda (_x) (func arg _x))
With the current one I wanted a fast currying function for usage primarily in 'find' and 'clean' for binary ops and without the additional overhead of the apply- and append operations necessary in a general curry
Perhaps we should have a second 'curry-nth' which can take more arguments and could additionally have an index parameter telling which parameter of the funtion should be curried?
Lutz
Posted: Wed May 23, 2007 5:32 pm
by Jeff
That sounds good. I just wish there were a useful way to do it recursively, because I really like the sound of "recurry" ;)
Posted: Wed May 23, 2007 6:00 pm
by cormullion
Anyone spare a few moments to explain in simple terms why curry (also known as "Schönfinkelisation" if the Wikipedia is to be believed) is useful? When would I use it?
Posted: Wed May 23, 2007 6:30 pm
by m i c h a e l
Hi cormullion!
The following is from the WikiP article you mentioned:
The practical motivation for currying is that very often the functions you get by supplying some but not all of the arguments to a curried function are useful; for example, many languages have a function or operator similar to plus_one. Currying makes it easy to define these functions.
In newLISP:
Code: Select all
> (set '+one (curry + 1))
(lambda (_x) (+ 1 _x))
> (+one 2)
3
> _
Useful? Maybe, but as Lutz said earlier, it's primarily used with the 'find' and 'clean' functions.
m i c h a e l
Posted: Wed May 23, 2007 6:33 pm
by Jeff
It's a fast way of applying a lambda when you know what the first argument should be every on every application. If you wanted to add 10 to every number in '(1 2 3 4 5), you could do:
Code: Select all
(map (lambda (n) (+ n 10)) '(1 2 3 4 5))
Or, you could do:
While this doesn't save a lot of time on that small example, when performing more complex applications, curry can save a heck of a lot of time.
Posted: Wed May 23, 2007 8:01 pm
by cormullion
Jeff wrote:It's a fast way of applying a lambda when you know what the first argument should be every on every application.
that's a good way of putting it. I shall steal that phrase for the next iteration of the "introduction to newlisp" (credited of course :-)
The one that sprung to mind immediately was:
cos I'm often writing this...
Posted: Wed May 23, 2007 8:03 pm
by cormullion
m i c h a e l wrote:The following is from the WikiP article you mentioned:
I propose that
curry be renamed
schönfinkelize, though.
Posted: Thu May 24, 2007 7:02 am
by Fanda
Since many people are used to 'curry' accepting any number of arguments , I would make:
curry - any number of arguments
curry1 - accepting 1 to 4 arguments - special functions for speed optimization
curry2
curry3
curry4
Fanda
Posted: Thu May 24, 2007 7:52 am
by rickyboy
Fanda wrote:Since many people are used to 'curry' accepting any number of arguments , I would make:
curry - any number of arguments
curry1 - accepting 1 to 4 arguments - special functions for speed optimization
curry2
curry3
curry4
Fanda
Good!
Posted: Thu May 24, 2007 8:11 am
by Fanda
Lutz wrote:Perhaps we should have a second 'curry-nth' which can take more arguments and could additionally have an index parameter telling which parameter of the funtion should be curried?
I like the idea of an index parameter:
Code: Select all
(define (curry-nth n f)
(letex (n n f f cargs (args))
(lambda () (apply f (append (0 n (args)) 'cargs (n (args)))))))
Code: Select all
(define f (curry-nth 1 explode 2))
(f "newLISP") => ("ne" "wL" "IS" "P")
(define f (curry-nth 1 explode 2 true))
(f "newLISP") => ("ne" "wL" "IS")
(define f (curry-nth 0 explode "apple"))
(f 2) => ("ap" "pl" "e")
(f 2 true) => ("ap" "pl")
(define f (curry-nth 1 append '(x y)))
(f '(a)) => (a x y)
(f '(a b)) => (a b x y)
(f '(a b) '(c d)) => (a b x y c d)
Fanda