Pergunta

I have define a macro that create a new class and then defines a constant that creates an instance of the newly defined class:

(defmacro my-class (name inst)
  `(progn
     (defclass ,name nil nil)
     (defconstant ,inst (make-instance ',name)))))

This seems to work in the REPL

(my-class x1025 y1025)

But when compiling it in a file doesn't work:

There is no class named COMMON-LISP-USER::X1025.
   [Condition of type SIMPLE-ERROR]

Restarts:
  0: [ABORT] Abort compilation.
  1: [*ABORT] Return to SLIME's top level.
  2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 8: #<CLOSURE (LABELS SWANK-BACKEND::RUN :IN SWANK-BACKEND:ADD-FD-HANDLER) {13228535}>>
  3: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: (SB-PCL::FIND-CLASS-FROM-CELL X1025 NIL T)
  1: ((:METHOD MAKE-INSTANCE (SYMBOL)) X1025) [fast-method]
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MAKE-INSTANCE (QUOTE X1025)) #<NULL-LEXENV>)
Foi útil?

Solução

The class may not be known during compile time in such a way that Lisp can create instances. The standard says that the class should be known during compilation - but not that instances can be created, before the DEFCLASS form is actually executed.

DEFCONSTANT may evaluate the MAKE-INSTANCE form during compile time. As you see in the backtrace, SBCL actually tries to call MAKE-INSTANCE.

You would need to make the class fully available during compile time. See EVAL-WHEN or put the class declaration in another file, which you need to load before.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top