On Wed, Jun 18, 2008 at 4:55 PM, Christophe Rhodes <csr21@...> wrote:
> Zach Beane <xach@...> writes:
>>> (eval-when (:compile-toplevel :execute)
>>> (%compiler-define-condition ...))
>>> (eval-when (:load-toplevel :execute)
>>> (%define-condition ...)))
>> Yes, this works perfectly for both LOAD and at the REPL. Thanks for
>> looking at it!
> OK, but I don't think this is the whole story. With this as the
> expansion, at the repl now %compiler-define-condition gets run twice,
> which I think is wasteful.
...and problematic in other ways as well, see below.
> My next stab at the solution was to expand into (the moral equivalent of)
> (eval-when (:compile-toplevel)
> (%compiler-define-condition ...))
> (eval-when (:load-toplevel :execute)
> (%define-condition ... (locally (declare (ftype (function (t) t) ,@all-readers)) ...))))
> am I right in thinking that code of the form
> (locally (declare (ftype function foo-x))
> (lambda (x) (foo-x x)))
> (defun bar (x)
> (declare (ftype function foo-x))
> (foo-x x))
> should not cause compiler warnings about foo-x? Secondly, does anyone
> have any energy to look at this?
That sounds reasonable to me. Ironically, in the DEFUN case the
undefined function warning comes from processing the FTYPE
declaration. (For LOCALLY as well, but not under EVAL, see below.)
It would be simple enough to pass a :SILENT T along the appropriate
code path, but sadly this does not make the (LOCALLY (DECLARE (FTYPE
...)) (LAMBDA (CONDITION STREAM) ...)) trick work:
When *EVALUATOR-MODE* is :COMPILE, and the DEFINE-CONDITION form is
processed by LOAD or EVAL, the FTYPE information from LOCALLY is lost
as *FREE-FUNS* is bound only for the declaration processing by EVAL,
and even if not, it would just gets rebound when entering the
compiler. Passing *FREE-FUNS* from EVAL to the compiler should be
possible, but requires more tinkering than I'm going to invest in this
now -- but if someone else wants to investigate...
> define-condition to evaluate %compiler-define-condition twice, so the
> workaround that I proposed to Zach could be merged in the meantime.)
I was going to do that, but then I noticed that the double-evaluation
breaks our package lock sematics & tests: (EVAL '(DEFINE-CONDITION
LOCKED-PACKAGE::FOO () ...)) should signal only a single package lock
violation, not two like it does with :EXECUTE.
...will think about this a bit more later.