Plaster

common-lisp
(defmacro eval-with (specs form) (flet ((normalize-spec (spec) (etypecase spec (list (destructuring-bind (name form) spec (cons name form))) (symbol (cons spec spec))))) (let ((specs (mapcar #'normalize-spec specs))) `(eval `(let (,,@(mapcar (lambda (b) ``(,',(car b) ',,(cdr b))) specs)) ,,form))))) ;; (let ((a 10) (b 20)) ;; (eval-with (a b) ;; '(+ a b))) ;; ;; = ;; ;; (let ((a 10) (b 20)) ;; (eval-with ((a a) (b b)) ;; '(+ a b))) ;; ;; = ;; ;; (let ((a 10) (b 20)) ;; (eval `(let ((a ',a) (b ',b)) ;; (+ a b)))) ;; ;; => 30 ;; (let ((a 10) (b 20)) ;; (eval-with ((a a) (b `(hi ,b))) ;; '(format nil "~a ~a" a b))) ;; ;; = ;; ;; (let ((a 10) (b 20)) ;; (eval `(let ((a '10) (b '(hi 20))) ;; (format nil "~a ~a" a b)))) ;; ;; => "10 (HI 20)"