X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=closure.el;h=82206289c51e61dd2bd50d2cabbc4a6c04ce57ab;hb=78d112053d1500b2fe8a166dec28a300f69ef18f;hp=fabab4f1261960b5d09487ce73aaaa771210f61c;hpb=f87bb7feacfe97e675fd65ef0b3da18a17c52930;p=elisp%2Fflim.git diff --git a/closure.el b/closure.el index fabab4f..8220628 100644 --- a/closure.el +++ b/closure.el @@ -1,21 +1,41 @@ (provide 'closure) +;; closure is one of following forms. +;; FUNCTION +;; (WRAPPER FUNCTION FV1 . FVS) +;; (PARTIAL-ARGS CLOSURE) + (defmacro closure-make (fun &rest fvs) - "Make closure from function FUN and free variable list FVS. + "Make a closure from a function FUN and free variables FVS. CAUTION: Do not assign to free variables." - (let* ((funv (make-symbol "funv")) - (args (make-symbol "args"))) - `(list - ,fun - (lambda (,funv ,args ,@fvs) - (apply ,funv ,args)) - ,@fvs))) + (if (null fvs) + fun + (let* ((funv (make-symbol "funv")) + (args (make-symbol "args"))) + `(list + (lambda (,funv ,args ,@fvs) + (apply ,funv ,args)) + ,fun + ,@fvs)))) + +(defmacro closure-partial-call (clo &rest args) + "Call partially." + `(list (list ,@args) ,clo)) (defun closure-call (clo &rest args) "Call closure." - (if (functionp clo) - (apply clo args) - (apply (cadr clo) (car clo) args (cddr clo)))) + (while + (and + (not (functionp clo)) + (if (cddr clo) + (progn + (setq args (cons (cadr clo) (cons args (cddr clo))) + clo (car clo)) + nil) + t)) + (setq args (append (car clo) args) + clo (cadr clo))) + (apply clo args)) (defun closure-compose (c1 c2) "Compose C1 and C2. @@ -41,4 +61,6 @@ If C1 and C2 is non-nil, C1 must be closure with one argument." (setq plus3 (closure-compose plus1 plus2)) (closure-call plus3 4) ; => 7 +(closure-call (closure-partial-call (closure-partial-call '+ 1 2 3) 4 5 6) 7 8 9) ;=> 45 + ) \ No newline at end of file