(defmacro symbol-macroletf (((symbol place)) &body body &environment environment) "Like SYMBOL-MACROLET but evaluate subforms just once up front. Binding multiple symbols in the same form has not yet been implemented." (multiple-value-bind (vars vals store-vars writer-form reader-form) (get-setf-expansion place environment) (let ((route (gensym (string symbol)))) `(let* (,@(mapcar #'list vars vals)) (flet ((,route () ,reader-form) ((setf ,route) (,(first store-vars)) ,writer-form)) (symbol-macrolet ((,symbol (,route))) ,@body)))))) ;; this works OK (let ((x 0) (v (copy-seq '(totally alone again)))) (symbol-macroletf ((s (elt v (incf x)))) (values (shiftf s 'wasted) s v))) ;; this doesn't (let ((x 0) (v (copy-seq '(totally alone again)))) (symbol-macroletf ((s (values (elt v (incf x)) (elt v (incf x))))) (shiftf s (values 'successful 'incubation))))