我試圖格式化任意表達式,例如(+ 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
閱讀保羅的意見後,似乎eval
是我的目的,最短和乾淨的解決方案。
這取決於你打算如何使用它。如果你正在開發一個詳細的調試宏,那麼你應該生成'(format ...)'表達式,引用第一個參數而不是第二個參數。如果這是用於REPL或某個解釋器,那就很好。除了你真的想觀察編譯的副作用或執行'expr'幾次之外,還有一個編譯的替代方法是'''(funcall(compile nil'(lambda(),expr)))'''不需要這個。 – acelent
@PauloMadeira感謝您的評論,我的目的是創建一個簡潔的測試套件,用於將功能輸出與預期結果進行比較。 (我編輯了我的問題)。生成一個'format'表達式聽起來像是過度殺毒,儘管我覺得它會比eval更靈活。 –
不要重新發明輪子:http://cliki.net/test%20framework – Sylwester