在不使用 eval 的情况下格式化表达式及其结果

Format both an expression and its result without eval

我正在尝试格式化一个任意表达式,比如说 (+ 2 3),同时,它的结果 5

我有以下内容:

(defun expr-and-result (expr)
  (format t "~a returns ~a~%" expr (eval expr)))

CL-USER> (expr-and-result '(+ 2 3))
  (+ 2 3) returns 5

虽然使用 eval 是一件简单的事情,但我很好奇如果没有它是否可以实现这种效果(因为我听说很多人说 eval 是要避免的)。

我知道引用参数是必要的,否则给定的表达式将被计算为调用 expr-and-result 的第一步,并且只能在 expr-and-result 中使用其结果。因此,任何可能的解决方案都需要引用输入,对吗?

我对宏有一些思考,但我觉得这是我正在寻找的错误方法。

编辑:我的目的是构建一个简单的测试套件,例如:

(progn
  (mapcar #'expr-and-result
          '((= (my-remainder 7 3) 1)
            (= (my-remainder 7 3) 2)))
  'end-of-tests)

Outputs: 
(= (MY-REMAINDER 7 3) 1) returns T
(= (MY-REMAINDER 7 3) 2) returns NIL
END-OF-TESTS

阅读 Paulo 的评论后,eval 似乎是对我来说最短、最干净的解决方案。

这是一个简单的宏:

(defmacro exec-and-report (form)
  `(format t "~S returns ~S~%" ',form ,form))
(macroexpand '(exec-and-report (+ 1 2)))
==>
(FORMAT T "~S returns ~S~%" '(+ 1 2) (+ 1 2)) ;
T
(exec-and-report (+ 1 2))
==>
(+ 1 2) returns 3
NIL

PS。我支持@Sylvester 的建议 not to reinvent the wheel