[Ecls-list] symbol-macro usage

Alexander Gavrilov angavrilov at gmail.com
Sat Feb 13 09:59:43 UTC 2010


As I understand, that file is an integration shim that activates
when both def and common modules are loaded, but allows them to
be used independently. Thus the 'common' one cannot directly
contain a reference to def. Although it can probably include a
placeholder in-package macro that by default directly expands
to the common lisp one.

I've added the actual author of that module to CC.

Alexander

> Your problem is related to a similar one, namely the use of DEFPACKAGE forms
> in compiled files. It is commonly agreed that DEFPACKAGE (and by that
> rational other package changing forms) should be compiled in separate files,
> precisely because otherwise there are problems like the one you find.
> 
> What is the problem then? The ANSI specification says that COMPILE-FILE must
> create a file that is used by the loader in a two-step way: reconstruct
> literal objects and execute forms. The order in which the object
> reconstruction happens is unclear and not specified. ECL, GCL and probably
> other lisps create the objects before ANY form is executed. Then any use of
> those objects is done by reference to the created objects.
> 
> Object creation must happen by a notion of "similarity" :
> http://www.lispworks.com/documentation/HyperSpec/Body/03_bdbb.htm For
> instance if the compiler finds a symbol hu.dwim.common::in-package in the
> compiled file, it will look up at load time an object with the same name
> IN-PACKAGE that is accessible from that package.
> 
> Note that the specification says "at load time" but it does not says at the
> time the form is executed. It is explicitely vague about when objects are
> created. Otherwise it would impose inefficient object creation mechanisms,
> such as lookup by name for *every* symbol in the file.
> 
> The problem in your example is that the file
> where hu.dwim.common::in-package appears is changing the symbol that this
> printed representation denotes. It does so at execution time, and in the
> case of ECL after a reference to a similar object has been resolved. In
> other words, you are changing what is "similar" while executing the first
> form.
> 
> In the case under question, I would advise to use DEFPACKAGE in a separate
> file and forge about explicit package manipulations.
> 
> Juanjo
> 
> On Sat, Feb 13, 2010 at 9:01 AM, Alexander Gavrilov <angavrilov at gmail.com>wrote:
> 
> > Hi,
> >
> > Could you also comment on the troubles that happen over here?
> >
> >
> > http://dwim.hu/darcsweb/darcsweb.cgi?r=HEAD%20hu.dwim.def;a=headblob;f=/integration/common.lisp
> >
> > Namely (and in case the above link is temporarily
> > unavailable), the original non-ecl code is as follows:
> >
> > #-ecl
> > (eval-when (:compile-toplevel :load-toplevel :execute)
> >  (unintern 'common-lisp:in-package :hu.dwim.common)
> >  (shadow "IN-PACKAGE" :hu.dwim.common))
> >
> > #-ecl
> > (eval-when (:compile-toplevel :load-toplevel :execute)
> >  ;; this export is not inside the above eval-when for a reason.
> >  (export 'hu.dwim.common::in-package :hu.dwim.common)
> >  (assert (not (eq 'hu.dwim.common::in-package 'common-lisp:in-package))))
> >
> > #-ecl
> > (def macro hu.dwim.common::in-package (package-name)
> >   ...)
> >
> > When one tries to use it with ECL, the compiling part seems
> > to work as expected, and the symbol is recorded in the fasl
> > as hu.dwim.common::in-package. However, when it is loaded,
> > the references are resolved before any code is executed,
> > so the assertion fails - and if it is removed, the macro
> > definition overwrites the original common-lisp macro with
> > disastrous consequences.
> >
> > Alexander
> >
> > > The error is very subtle. You have to go here
> > >    http://www.lispworks.com/documentation/HyperSpec/Body/03_bcaa.htm
> > >
> > > define-symbol-macro does not have compile-time side effects. That means
> > that
> > > when the compiler reaches the form (defvar a m) it does not know that M
> > is a
> > > macro! This causes a load time error because the code is designed to find
> > > out the value of the variable "M", not to use "tstst".





More information about the ecl-devel mailing list