(define-syntax curried
(syntax-rules ()
[(_ () exp ...)
(lambda args
(if (null? args)
(begin exp ...)
(apply (begin exp ...) args)))]
[(_ (x x1 ...) exp ...)
(letrec ([rec (case-lambda
[() rec]
[(x x1 ...) (begin exp ...)]
[(x x1 ... . rest) (apply (rec x x1 ...) rest)]
[fewer-args
(let ([waiting-for-more
(lambda (rec fewer-args)
(lambda more-args (apply rec (append fewer-args more-args))))])
(waiting-for-more rec fewer-args))])])
rec)]
[(_ (x x1 ... . rest) exp ...)
(letrec ([rec (case-lambda
[() rec]
[(x x1 ... . rest) (begin exp ...)]
[fewer-args
(let ([waiting-for-more
(lambda (rec fewer-args)
(lambda more-args (apply rec (append fewer-args more-args))))])
(waiting-for-more rec fewer-args))])])
rec)]
[(_ args exp ...) (lambda args exp ...)]))
(define-syntax define-curried
(syntax-rules ()
[(_ (f . args) . body) (define f (curried args . body))]))