# [plt-scheme] Currying functions?

On Fri, 3 Feb 2006, Gregory Woodhouse wrote:
>* I was just browsing the language manual and came across an interesting
*>* function: procedure-arity. Now, it just happens that yesterday I had
*>* occasion to want to create a curried version of a binary operator (as
*>* part of the evaluator I'm working on, where I wanted to map it across an
*>* argument list), so I searched for curry and currying in Help Desk and
*>* found nothing.
*
Hi Gregory,
You may want to check the Swindle collection; it has a a currying
definition that you might find handy.
http://ja.soegaard.net/planet/html/collects/swindle/readme.txt
>* Well, in the case of functions of arity 2 it's easy:
*>*
*>* > (define (curry2 f)
*>* (lambda (x)
*>* (lambda (y)
*>* (f x y))))
*>* > (define a (curry2 +))
*>* > ((a 2) 3)
*>* 5
*>*
*>* but to create a curried version of an arbitrary function, you need to
*>* know it's arity. Maybe it's possible to create a curried version of a
*>* function taking a variable number of arguments, but I'm not sure how it
*>* would be done.
*
Maybe something like this would work for you:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module currify mzscheme
(provide currify)
(define (currify f)
(let ((N (procedure-arity f)))
(letrec
((grab-rest-args
(lambda (n reversed-args-so-far)
(if (= n N)
(apply f (reverse reversed-args-so-far))
(lambda (x)
(grab-rest-args (add1 n)
(cons x reversed-args-so-far)))))))
(cond
((and (number? N) (= N 0)) f)
((number? N)
(lambda (first-arg)
(grab-rest-args 1 (list first-arg))))
(else
(error 'currify
"Don't know how to handle procedure arity ~s" N)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
For example:
;;;;;;
>* (define take-three (currify (lambda (a b c) (printf "~s~s~s~%" a b c))))
*>* (take-three 1)
*#<procedure:.../dyoo/currify.ss:11:18>
>* ((take-three 1) 2)
*#<procedure:.../dyoo/currify.ss:11:18>
>* (((take-three 1) 2) 3)
*123
;;;;;;
Best of wishes!