在不使用 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
我正在尝试格式化一个任意表达式,比如说 (+ 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