chickadee » srfi-232 » curried

(curried formals body)syntax

formals is anything that could appear as the formals argument of a lambda expression. As with lambda, body is a sequence of one or more expressions.

Normally, a curried evaluates to a procedure which can be applied to any number of arguments. If it is applied to fewer parameters than its formals list indicates, then the given arguments are bound and a new curried procedure which accepts more parameters is returned. When all parameters have been bound, the body of the procedure is evaluated. For example,

(let* ((foo0 (curried (x y z) (list x (list y z))))
       (foo1 (foo0 'a 'b)))
  (foo1 'c))
;; => (a (b c))

Here, foo0 is applied to two arguments, giving another procedure in which x is bound to a and y to b. This is then applied to c, which gives a value for z. All of the original parameters now have bindings, so the body of the procedure is evaluated.

curried procedures can also be applied "all at once":

(foo0 'a 'b 'c) ; => (a (b c))

If a normal curried procedure is applied to too many parameters (i.e. more than appear in its formals list), then the rest are passed to the value of the body (which must be a procedure):

(let ((bar (curried (a b)
             (lambda (c d) (+ (* a b) (- c d))))))
  (bar 2 3 7 5))
; => 8

A curried procedure with a "dotted-tail" formals list will bind a list of any excess arguments to the final parameter:

(let ((foo (curried (a b . rest)
             (apply + (* a b) rest))))
  (list ((foo 2) 3 4)
        (foo 2 3 4 5)
        (foo 2 3)))
;; => (10 15 6)

The procedure is applied as soon as all of the normal parameters have bindings. So, in the above example, (foo 2 3) binds rest to ().

There are a few important corner cases. A curried procedure with an empty formals list evaluates to its body:

(curried () 'b) ; => b

If formals is a single identifier, then curried works like lambda:

(let ((baz (curried xs (list (car xs) (cdr xs)))))
  (baz 2 3 4 5))
; => (2 (3 4 5))