Why does calling `make-instance` in `let` work differently?

Bar*_*Lew 5 sbcl common-lisp let clos

I'm exploring some possibilities of Common Lisp syntax and I wanted to make an :around method on make-instance to return some arbitrary value in some cases. For sake of simplicity, let it be nil, when I don't pass a needed argument. And it works, but not when calling in let:

(defclass foo ()
  ((bar :initarg := :initform '())))

(defmethod make-instance :around ((type (eql 'foo)) &key =)
  (if (not =) nil (call-next-method)))

(print (make-instance 'foo))    ;; => NIL

(print (let ((x (make-instance 'foo))) x)) ;; => #<FOO {10037EEDF3}> 
Run Code Online (Sandbox Code Playgroud)

Can somebody explain this situation? Why is that so? Does SBCL try to be smart or is it actually a standard thing to be done? I know that I can work around it by using apply:

(print (let ((x (apply #'make-instance (list 'foo)))) x)) ;; => NIL
Run Code Online (Sandbox Code Playgroud)

But I don't want to rely on this sort of workaround. Actually I can use a regular function for that and it's OK, but I want to understand why it works this way and if this behaviour can be disabled.

Rai*_*wig 4

MAKE-INSTANCE看起来像是SBCL (-> CTOR) 中常量类名的优化尝试之一...

这似乎有效:

(defmethod make-instance :around ((class (eql (find-class 'foo)))
                                  &rest initargs
                                  &key =
                                  &allow-other-keys)
  (declare (ignorable initargs))
  (if (not =) nil (call-next-method)))
Run Code Online (Sandbox Code Playgroud)

但询问 SBCL 专家或提交错误报告可能很有用......