(defmacro fbind ((&rest bindings #| forces bindings to be a list |#) &body body) (let* ((names (mapcar (function first) bindings)) (initforms (mapcar (function second) bindings)) (funs (mapcar (lambda (x) (declare (ignore x)) (gensym)) bindings))) `(let ,(mapcar (function list) funs initforms) (flet ,(mapcar (lambda (name fun) `(,name (&rest args) (apply ,fun args))) names funs) ,@body)))) (let ((counter 0)) (flet ((get-function (x) (lambda (a) (+ a x)))) (format t "counter before: ~a~%" counter) (fbind ((fun1 (progn (incf counter) (get-function 5))) (fun2 (get-function 10))) (format t "counter after: ~a~%" counter) (prog1 (list (fun1 5) (fun1 5) (fun2 10) (fun2 10)) (format t "counter way after: ~a~%" counter))))) counter before: 0 counter after: 1 counter way after: 1 (10 10 20 20)