weird compilation effects with progn + defclass + macro

Bug #1893749 reported by Jan Igger
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Invalid
Undecided
Unassigned

Bug Description

;; Code:

(require 'closer-mop) ;; 1

(defmacro gen () ;; 2
  (let ((type (sb-mop:slot-definition-type
               (first (sb-mop:class-slots (find-class 'A))))))
    (unless (equal type 'boolean) (error "No type specified for the slot."))))

(progn ;; 3
  (defclass A () ((x :type boolean))) ;; (x :type boolean) -> (x)
  (c2mop:ensure-finalized (find-class 'A))
  (gen))

#|
1. eval-defun expressions 1 and 2
2. compile-defun expression 3
3. observe error: "no class named common-lisp-user::a" (which is unexpected)
4. compile-defun again, error is gone
5. remove type specification in class A
6. compile-defun expression 3, observe no error (should be error)
7. compile-defun expression 3 again, observe error "No type specified for the slot"
unlike compile-defun, eval-defun produces expected behavior.
What's happening here?

SBCL 2.0.5

Linux archbox 5.7.9-arch1-1 #1 SMP PREEMPT Thu, 16 Jul 2020 19:34:49 +0000 x86_64 GNU/Linux

(:SLYNK :QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX
 :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :X86-64 :GENCGC :64-BIT :ANSI-CL
 :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LINUX :LITTLE-ENDIAN
 :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS
 :SB-THREAD :SB-UNICODE :SBCL :UNIX)
|#

Revision history for this message
Stas Boukarev (stassats) wrote :

You are defining the class and expanding the macro at different times, so each time you edit your form the macro gets the previous definition.

Changed in sbcl:
status: New → Invalid
Revision history for this message
Jan Igger (le-perv) wrote :

In retrospect this seems such an obvious thing. Thanks for pointing it out. Going to use (eval '(gen)) now.

Revision history for this message
Jan Igger (le-perv) wrote :

In case someone stumbles into this issue, I found a much cleaner solution than a straightlaced eval: eval-when. It can shift evaluation to compile-time. Like this:

(progn ;; 3
  (eval-when (:compile-toplevel :load-toplevel :execute)
    (defclass A () ((x :type boolean))) ;; (x :type boolean) -> (x)
    (c2mop:ensure-finalized (find-class 'A)))
  (gen))

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.