Re: apparently undefined function called by macro




Greg Bacon wrote:
;(eval-when (:load-toplevel :compile-toplevel :execute)
(defun id (x) x)
;)

Note the semicolons here which get rid of the (eval-when ...).

(defmacro define-foo-class (name slots)
`(defclass ,name ()
,(mapcar #'id slots)))

If this macro has to be expanded as a part of compiling code, then the
function ID has exist.

A compiler does not automatically define the functions created by
DEFUN. Of course, it reads them and translates them to the object code.
But it does not install them in its own image.

A macro is a program that runs in the compiler's image. If it calls any
functions, they have to exist in the compiler's image also. That
commented-out EVAL-WHEN is what tells the compiler to not only compile
the DEFUN but also define the function so that the macro can work.

If I try to load it in a fresh image, clisp complains about undefined id:

[1]> (asdf:oos 'asdf:load-op :foo)
; loading system definition from foo.asd into #<PACKAGE ASDF0>
;; Loading file foo.asd ...
; registering #<SYSTEM FOO #x102A2839> as FOO
;; Loaded file foo.asd
;; Compiling file /tmp/asdf/packages.lisp ...
;; Wrote file /tmp/asdf/packages.fas
;; Loading file /tmp/asdf/packages.fas ...
;; Loaded file /tmp/asdf/packages.fas
;; Compiling file /tmp/asdf/foo.lisp ...
*** - FUNCTION: undefined function ID

Note that the terror occurs in "Compiling file /tmp/asdf/foo.lisp".
Foo.lisp isn't being loaded, but compiled.

For instance look what processing happened immediately before with
packages.lisp:

;; Compiling file /tmp/asdf/packages.lisp ...
;; Wrote file /tmp/asdf/packages.fas
;; Loading file /tmp/asdf/packages.fas ...
;; Loaded file /tmp/asdf/packages.fas

It was compiled to produce a .fas file, which was then loaded.

Your foo.lisp is stuck at the first step: compiling! There was never an
attempt to load it; things didn't get that far.

[...]

Loading by hand, i.e., (progn (load "packages.lisp") (load "foo.lisp")),

But (load "foo.lisp") doesn't compile it! You're skipping the step that
doesn't work.

In Lisp we can load things without compiling them, no surprises there.

They run, just a tad more slowly.

is no problem, and as you can guess from the commented lines, wrapping
ID in EVAL-WHEN is also a workaround.

That is not a workaround; that's the standard ANSI CL way to make sure
a function is available within the compiler at macro-expansion time.

Well, hmm, my misunderstanding is more basic than ASDF or even the
reader. After removing the initial IN-PACKAGE form from foo.lisp,
COMPILE-FILE still complains about undefined ID.

It has nothing to do with packaging. The compiler has no problem with
the symbol ID itself, the error is that there is no function called ID.
If you change the package in which ID is read, it simply switches its
complaint to a different ID, since there is no function called ID in
this package, nor in that one.

.



Relevant Pages

  • Re: Nested macros
    ... PCL mentions that it's necessary if I want to use a macro in the ... The compiler knows that macro. ... (defun bar (...) ... ; caught STYLE-WARNING: ...
    (comp.lang.lisp)
  • Re: Question about compilation/evaluation environments
    ... I guess it depends on what you mean by evaluating some code. ... In this case, the form is the macro function, aka macro ... invocation of compiled code produced by a compiler. ... ANY OF THESE FACILITIES MIGHT SHARE THE SAME EXECUTION ...
    (comp.lang.lisp)
  • Re: How to define a const and initialize it?
    ... > do the same work as const int MYCONST will do.... ... But the thing is that macro substitution takes ... C++ compiler isn't even aware of its existence. ... This Item might better be called "prefer the compiler to the preprocessor," because #define is often ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Preprocessor and sizeof()
    ... coming from a compiler vendor baffled me even more. ... "standard", i.e. poor) ... its headers and libraries, and in some cases is required to, as some ... into an issue with one such case, namely the offsetof macro. ...
    (comp.lang.c)
  • Re: Sacla loop: a new loop implementation
    ... the compiler is able to deduce enough about the type of thing ... That requires only that type information is *sometimes* ... > necessary information for the macro to expand. ... "statically typed language". ...
    (comp.lang.lisp)