23 lines
988 B
Common Lisp
23 lines
988 B
Common Lisp
(in-package #:syrup)
|
|
|
|
(defmacro curry ((fun &rest args) &key (blank '*) (rest nil))
|
|
"Construct a lambda around FUN, where arguments not marked with * are pre-filled with the specified forms.
|
|
e.g. (curry (- * 2)) => (lambda (x) (- x 2))
|
|
:BLANK (default *) - specify the blank symbol
|
|
:REST (default NIL) - if true, add a &rest argument to the end of the lambda"
|
|
(let ((outer-args nil) (inner-args nil))
|
|
(dolist (arg args)
|
|
(if (eql arg blank)
|
|
(let ((sym (gensym)))
|
|
(push sym outer-args)
|
|
(push sym inner-args))
|
|
;; else
|
|
(push arg inner-args)))
|
|
;; reverse the lists, since we used PUSH to build them
|
|
(setf outer-args (nreverse outer-args)
|
|
inner-args (nreverse inner-args))
|
|
;; now create the lambda
|
|
(if rest
|
|
(let ((rest-sym (gensym)))
|
|
`(lambda (,@outer-args &rest ,rest-sym) (apply (function ,fun) ,@inner-args ,rest-sym)))
|
|
`(lambda ,outer-args (,fun ,@inner-args)))))
|