如何在SBCL中创建解释型函数而非编译型函数?
Great question! The problem with your initial approach is that SBCL treats top-level definitions like defun specially—even when wrapped in a let binding for sb-ext::*evaluator-mode*, the defun itself gets compiled by default, ignoring the binding you set. Here's why and how to fix it:
Why Your Original Code Didn't Work
When you run:
(let ((sb-ext::*evaluator-mode* :interpret)) (defun bar (x) (+ x 1)))
SBCL processes the defun as a top-level compilation form before evaluating the let body's runtime environment. The *evaluator-mode* binding only affects code that's evaluated at runtime via eval, not top-level forms that the compiler picks up directly.
Fix 1: Use eval with *evaluator-mode* Binding
To force the defun to be interpreted, you need to pass its expression to eval—this ensures the *evaluator-mode* setting is respected during evaluation:
(let ((sb-ext::*evaluator-mode* :interpret)) (eval '(defun bar (x) (+ x 1))))
Now if you check:
CL-USER> (compiled-function-p #'bar) NIL
This confirms bar is an interpreted function.
Fix 2: Use sb-ext:interpret Directly
SBCL provides a dedicated function sb-ext:interpret that bypasses the compiler and uses the interpreter for a given expression. This is even cleaner:
(sb-ext:interpret '(defun bar (x) (+ x 1)))
Running (compiled-function-p #'bar) will also return NIL here, since sb-ext:interpret explicitly uses the interpreter regardless of the default *evaluator-mode* setting.
Key Takeaway
sb-ext::*evaluator-mode*controls the behavior of theevalfunction, not top-level forms processed directly by the compiler.- To create interpreted functions, either wrap the
defunform inevalwith the mode set to:interpret, or usesb-ext:interpretdirectly.
内容的提问来源于stack exchange,提问作者Jérôme Radix

