February 3, 2007 — jao

One of the few things i miss when programming in Scheme is ML-style function currying. ML, Haskell and OCaml come with this handy feature that allows you to obtain new functions from a given one by calling it with an ‘incomplete’ number of arguments.

Fortunately, we have macros in our programmable programming language, and actually there’re lots of them floating around providing implementations of currying in Lisp. But today, Piet Delport posted (during a discussion in #scheme) the nicest currying macro i’ve seen so far:

(define-syntax curried (syntax-rules () ((curried () body ...) (lambda () body ...)) ((curried (arg) body ...) (lambda (arg) body ...)) ((curried (arg args ...) body ...) (lambda (arg . rest) (let ((next (curried (args ...) body ...))) (if (null? rest) next (apply next rest))))))) (define-syntax define-curried (syntax-rules () ((define-curried (name args ...) body ...) (define name (curried (args ...) body ...))))) ;;;; Sample usage: (define-curried (foo x y z) (+ x (/ y z))) ;; foo has arity 3 ((foo 3) 1 2) ;; (foo 3) is a procedure with arity 2 ((foo 3 1) 2) ;; (foo 3 2) is a procedure with arity 1

This code shows the elegance and power of hygienic syntax-rules macros, which allow you to extend the language seamlessly, incorporating new features as if they were native. It also makes for a pretty instructive demonstration of how to take advantage of higher-order functions and recursion, nicely combined. All that in just a few lines!

If you’re new to Scheme and want to learn more about similar magic, be sure to read JRM’s syntax-rules Primer for the Merely Eccentric. You’ll have a great time.