3 ;; closure is one of following forms.
5 ;; (WRAPPER FUNCTION FV1 . FVS)
6 ;; (PARTIAL-ARGS CLOSURE)
8 (defmacro closure-make (fun &rest fvs)
9 "Make a closure from a function FUN and free variables FVS.
10 CAUTION: Do not assign to free variables."
13 (let* ((funv (make-symbol "funv"))
14 (args (make-symbol "args")))
16 (lambda (,funv ,args ,@fvs)
21 (defmacro closure-partial-call (clo &rest args)
23 `(list (list ,@args) ,clo))
25 (defun closure-call (clo &rest args)
32 (setq args (cons (cadr clo) (cons args (cddr clo)))
36 (setq args (append (car clo) args)
40 (defun closure-compose (c1 c2)
43 If either C1 or C2 is nil, another one is returned.
44 If C1 and C2 is non-nil, C1 must be closure with one argument."
51 (closure-call c1 (apply 'closure-call c2 args)))
56 (setq c1 (let ((a 1)) (closure-make (lambda (b) (+ a b)) a)))
57 (closure-call c1 2) ; => 3
59 (let ((a 1)) (setq plus1 (closure-make (lambda (b) (+ a b)) a)))
60 (let ((a 2)) (setq plus2 (closure-make (lambda (b) (+ a b)) a)))
61 (setq plus3 (closure-compose plus1 plus2))
62 (closure-call plus3 4) ; => 7
64 (closure-call (closure-partial-call (closure-partial-call '+ 1 2 3) 4 5 6) 7 8 9) ;=> 45