Message from discussion apparently undefined function called by macro
From: "Kaz Kylheku" <kkylh...@gmail.com>
Subject: Re: apparently undefined function called by macro
Date: 29 Jun 2006 17:23:58 -0700
Content-Type: text/plain; charset="iso-8859-1"
X-Trace: posting.google.com 1151627042 6521 127.0.0.1 (30 Jun 2006 00:24:02 GMT)
NNTP-Posting-Date: Fri, 30 Jun 2006 00:24:02 +0000 (UTC)
X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322),gzip(gfe),gzip(gfe)
Injection-Info: y41g2000cwy.googlegroups.com; posting-host=126.96.36.199;
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:
> > (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
;; 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
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.