(defmacro symbol-macroletf-helper (store-vars writer-form reader-form) (declare (ignore store-vars writer-form)) reader-form) (define-setf-expander symbol-macroletf-helper (store-vars writer-form reader-form) (values '() '() store-vars writer-form reader-form)) (defmacro symbol-macroletf ((&rest bindings) &body body &environment environment) "Like SYMBOL-MACROLET but evaluate subforms just once up front." (loop with (vars vals store-vars writer-form reader-form) for (symbol place) in bindings do (setf (values vars vals store-vars writer-form reader-form) (get-setf-expansion place environment)) nconc (mapcar #'list vars vals) into let*-bindings collect `(,symbol (symbol-macroletf-helper ,store-vars ,writer-form ,reader-form)) into symbol-macrolet-bindings finally (return `(let* (,@let*-bindings) (symbol-macrolet (,@symbol-macrolet-bindings) ,@body)))))