From: Peter Seibel
Subject: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <m3acrebhvh.fsf@javamonkey.com>
Clearly, if one wants to use a macro in the same file where it is
defined, and compile the file, you need to put the macro definition
before any uses of it. And in compiler-only implementations the same
would be true when LOADing a file. My question is, is there anywhere
in the spec that explicitly says anything about the need/desirability
to define macros before EVALing code that uses them? Presumably in an
implementation with a not-even-minimally-compiling interpreter,
EVALing, say, a DEFUN that contains calls to a not-yet-defined macro
would "work" as long as the macro was defined before the function was
called so I'd imagine it's not explicitly disallowed. Just wondering
if I missed anything.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp

From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <4ekgq8ntw.fsf@franz.com>
Peter Seibel <·····@javamonkey.com> writes:

> Clearly, if one wants to use a macro in the same file where it is
> defined, and compile the file, you need to put the macro definition
> before any uses of it. And in compiler-only implementations the same
> would be true when LOADing a file. My question is, is there anywhere
> in the spec that explicitly says anything about the need/desirability
> to define macros before EVALing code that uses them? Presumably in an
> implementation with a not-even-minimally-compiling interpreter,
> EVALing, say, a DEFUN that contains calls to a not-yet-defined macro
> would "work" as long as the macro was defined before the function was
> called so I'd imagine it's not explicitly disallowed. Just wondering
> if I missed anything.

3.1.2.1.2  - second paragraph, last sentence.

Further, the sections under this page give the semantics for form
evaluation of the three different kinds of forms in question, and
since they are not compatible, it is easy to conclude that one must
be sure that the form is recognized as a macro form before the time
that it is evaluated.  If it is recoginized as a function form (by
virtue of the macro not being defined yet), then it obviously can't
be evaluated under macro-form semantics.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Peter Seibel
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <m31xcqbfw9.fsf@javamonkey.com>
Duane Rettig <·····@franz.com> writes:

> Peter Seibel <·····@javamonkey.com> writes:
>
>> Clearly, if one wants to use a macro in the same file where it is
>> defined, and compile the file, you need to put the macro definition
>> before any uses of it. And in compiler-only implementations the
>> same would be true when LOADing a file. My question is, is there
>> anywhere in the spec that explicitly says anything about the
>> need/desirability to define macros before EVALing code that uses
>> them? Presumably in an implementation with a
>> not-even-minimally-compiling interpreter, EVALing, say, a DEFUN
>> that contains calls to a not-yet-defined macro would "work" as long
>> as the macro was defined before the function was called so I'd
>> imagine it's not explicitly disallowed. Just wondering if I missed
>> anything.
>
> 3.1.2.1.2  - second paragraph, last sentence.
>
> Further, the sections under this page give the semantics for form
> evaluation of the three different kinds of forms in question, and
> since they are not compatible, it is easy to conclude that one must
> be sure that the form is recognized as a macro form before the time
> that it is evaluated. If it is recoginized as a function form (by
> virtue of the macro not being defined yet), then it obviously can't
> be evaluated under macro-form semantics.

Yes, that's all true. But it doesn't really get to my question--maybe
I wasn't clear. Or maybe it's just a dumb question. Anyway, I was
thinking about this case. Suppose I type this at the REPL:

  (eval '(defun foo () (some-macro-yet-to-be-defined)))

Now suppose in the implementation I'm using, EVAL doesn't even
minimally compile the definition. (Sub question: is that a conforming
implementation. I assume so.)

Since it hasn't compiled the definition it doesn't have to decide yet
what kind of form

  (some-macro-yet-to-be-defined)

is. And it won't need to until I call FOO. So it seems I have a chance
to define it before I call FOO and still have FOO behave as if I had
defined the macro in advance. I was just wondering if there was some
other reason that, in such an implementation, that that wouldn't
"work".

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <44qhm8iac.fsf@franz.com>
Peter Seibel <·····@javamonkey.com> writes:

> Duane Rettig <·····@franz.com> writes:
> 
> > Peter Seibel <·····@javamonkey.com> writes:
> >
> >> Clearly, if one wants to use a macro in the same file where it is
> >> defined, and compile the file, you need to put the macro definition
> >> before any uses of it. And in compiler-only implementations the
> >> same would be true when LOADing a file. My question is, is there
> >> anywhere in the spec that explicitly says anything about the
> >> need/desirability to define macros before EVALing code that uses
> >> them? Presumably in an implementation with a
> >> not-even-minimally-compiling interpreter, EVALing, say, a DEFUN
> >> that contains calls to a not-yet-defined macro would "work" as long
> >> as the macro was defined before the function was called so I'd
> >> imagine it's not explicitly disallowed. Just wondering if I missed
> >> anything.
> >
> > 3.1.2.1.2  - second paragraph, last sentence.
> >
> > Further, the sections under this page give the semantics for form
> > evaluation of the three different kinds of forms in question, and
> > since they are not compatible, it is easy to conclude that one must
> > be sure that the form is recognized as a macro form before the time
> > that it is evaluated. If it is recoginized as a function form (by
> > virtue of the macro not being defined yet), then it obviously can't
> > be evaluated under macro-form semantics.
> 
> Yes, that's all true. But it doesn't really get to my question--maybe
> I wasn't clear. Or maybe it's just a dumb question. Anyway, I was
> thinking about this case. Suppose I type this at the REPL:
> 
>   (eval '(defun foo () (some-macro-yet-to-be-defined)))

Leave off the eval; the E in REPL does that for you (if you typed the
exact form above into a REPL, you'd likely get an undefined-variable
error on 'foo).

> Now suppose in the implementation I'm using, EVAL doesn't even
> minimally compile the definition.

It is not required to do so, but as a user, you are not at liberty to
assume that it is not immediately compiled.

 (Sub question: is that a conforming
> implementation. I assume so.)

Yes.

> Since it hasn't compiled the definition it doesn't have to decide yet
> what kind of form
> 
>   (some-macro-yet-to-be-defined)
> 
> is.

If you are wearing a user's hat, then I repeat the warning: you are
not allowed to assume that it is not already compiled.  However,
if you are wearing a "want to know what implementor's think" hat,
then you are touching on another of the "late-binding" issues that
tends to cause us to decide not to compile every form.  It allows
a user to (not portably, but almost always in Allegro CL) define
functions and then macros that they use later on, so as not to
force a bottom-up aproach to thinking about a problem.

> And it won't need to until I call FOO. So it seems I have a chance
> to define it before I call FOO and still have FOO behave as if I had
> defined the macro in advance. I was just wondering if there was some
> other reason that, in such an implementation, that that wouldn't
> "work".

There is one caveat, even in Allegro CL where we generally don't
compile forms automatically, there are a few times when we do compile
forms automatically; an effective-method is one such case, though
you generally don't see the source for that anyway (and it is under
control of an internal variable).  Also, the old defadvice facility
had excl:*compile-advice* associated with it, so you might find
compilation taking place there unexpectedly as well.


-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Don Geddis
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <876521cktb.fsf@sidious.geddis.org>
> Peter Seibel <·····@javamonkey.com> writes:
>> Suppose I type this at the REPL:
>>   [...]
>>   (defun foo () (some-macro-yet-to-be-defined))
>> Now suppose in the implementation I'm using, EVAL doesn't even
>> minimally compile the definition.

Duane Rettig <·····@franz.com> wrote on 12 Jan 2005 13:1:
> It is not required to do so, but as a user, you are not at liberty to
> assume that it is not immediately compiled.
> [...] you are touching on another of the "late-binding" issues that
> tends to cause us to decide not to compile every form.  It allows
> a user to (not portably, but almost always in Allegro CL) define
> functions and then macros that they use later on, so as not to
> force a bottom-up aproach to thinking about a problem.

Is there anything from stopping a conforming implementation from
remembering all the cross references and undefined calls, and then
silently and automatically re-compiling all dependent functions if you
ever redefined a macro (or defined a macro for the first time that
was either undefined or previously defined as a function)?

Obviously, a user of portable code couldn't rely on this.  But I wonder
whether something in the spec requires this sequence:
        (defmacro foo () 1)
        (defun bar () (foo))
        (defmacro foo () 2)
        (bar)
to return 1 instead of 2 when compiled.  It seems probably not, since you're
saying (if I understand you correctly) that Allegro will return 2 when
typed into the REPL, by virtue of "late binding".  And the CL spec tries
really hard to make interpreters and compilers have the same semantics.
So surely a very clever compiler is allowed to also return 2.  Yes?

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
Happiness:  The agreeable sensation of contemplating the misery of others.
From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <4k6qhxhs5.fsf@franz.com>
Don Geddis <···@geddis.org> writes:

> > Peter Seibel <·····@javamonkey.com> writes:
> >> Suppose I type this at the REPL:
> >>   [...]
> >>   (defun foo () (some-macro-yet-to-be-defined))
> >> Now suppose in the implementation I'm using, EVAL doesn't even
> >> minimally compile the definition.
> 
> Duane Rettig <·····@franz.com> wrote on 12 Jan 2005 13:1:
> > It is not required to do so, but as a user, you are not at liberty to
> > assume that it is not immediately compiled.
> > [...] you are touching on another of the "late-binding" issues that
> > tends to cause us to decide not to compile every form.  It allows
> > a user to (not portably, but almost always in Allegro CL) define
> > functions and then macros that they use later on, so as not to
> > force a bottom-up aproach to thinking about a problem.
> 
> Is there anything from stopping a conforming implementation from
> remembering all the cross references and undefined calls, and then
> silently and automatically re-compiling all dependent functions if you
> ever redefined a macro (or defined a macro for the first time that
> was either undefined or previously defined as a function)?

Actually, Screamer does just this.  But Screamer is not a conforming
program, since it redefines CL functions.  And I doubt that Screamer's
author ever intended that it purport to be a conforming implementaion.

> Obviously, a user of portable code couldn't rely on this.  But I wonder
> whether something in the spec requires this sequence:
>         (defmacro foo () 1)
>         (defun bar () (foo))
>         (defmacro foo () 2)
>         (bar)
> to return 1 instead of 2 when compiled.

The key phrase is "when compiled", so the real question is:
when did you compile bar?  See 3.2.2.3, first paragraph.
If you insert a (compile 'bar) right after the defun of bar,
then that paragraph applies, and the call to bar is required
to return 1.  (note that if the implementation has already compiled
bar, then the (compile 'bar) is a noop).  If you instead insert
a (compile 'bar) after the second foo definition, then the results
depend on whether the implementation is always compiling as its
way of interpreting.

> It seems probably not, since you're
> saying (if I understand you correctly) that Allegro will return 2 when
> typed into the REPL, by virtue of "late binding".

The earliest binding time is at compile-time, and the latest binding
time is at eval (more specifically, macroexpand) time, so the real
answer is "it depends".

>  And the CL spec tries
> really hard to make interpreters and compilers have the same semantics.

Yes, except for the obvious: compiled functions are compiled :-)
(this would be tautological, except that since compiling forces
the binding of macro definitions, it is in fact the compilation
that causes the difference.  This also implies that compilation is
in enmity with late-binding, so if you want your functionality to
maximize late-binding, then you shouldn't compile it.)

> So surely a very clever compiler is allowed to also return 2.  Yes?

No. A compile cleverly _placed_ is allowed to return 2.

Incidentally, your example makes an excellent demonstration for
Peter's question about my late-binding comment - I don't normally
program this way, since it is non-portable, so it was hard for me
to give an example of how late-binding (and indeed, separation
of compilation and evaluation environments) might be used.  Note that
if we place similar forms to yours (with modifications to account
for eval-when issues) into a file and compile it:

CL-USER(1): (shell "cat foo.cl")
(defmacro foo () 1)
(eval-when (compile load eval)
  (defun bar () (foo)))
(defmacro foo () 2)
(print (bar))
(eval-when (compile)
  (print (bar)))
0
CL-USER(2): (compile-file "foo.cl")
;;; Compiling file foo.cl
Warning: FOO is defined more than once as `operator' in file foo.cl.

2 
;;; Writing fasl file foo.fasl
;;; Fasl write complete
#P"foo.fasl"
T
T
CL-USER(3): (load "foo.fasl")
; Fast loading /tmp_mnt/net/gemini/home/duane/foo.fasl
Warning: FOO is defined more than once as `operator' in file foo.cl.

1 
T
CL-USER(4): 

We find the late-binding behavior.  I am hoping that anyone who has
been following this thread (and understanding it :-) can tell me
why at compile-time 2 is printed, and at load-time 1 is printed?

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Don Geddis
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87acrbc1ym.fsf@sidious.geddis.org>
Duane Rettig <·····@franz.com> wrote on 13 Jan 2005 11:1:
>> Obviously, a user of portable code couldn't rely on this.  But I wonder
>> whether something in the spec requires this sequence:
>>         (defmacro foo () 1)
>>         (defun bar () (foo))
>>         (defmacro foo () 2)
>>         (bar)
>> to return 1 instead of 2 when compiled.
>
> The key phrase is "when compiled", so the real question is:
> when did you compile bar?  See 3.2.2.3, first paragraph.
> If you insert a (compile 'bar) right after the defun of bar,

Excellent point.  So we should consider this code instead:
        (defmacro foo () 1)
        (defun bar () (foo))
        (compile 'bar)
        (defmacro foo () 2)
        (bar)
typed into the REPL.

> then that paragraph applies, and the call to bar is required
> to return 1.  (note that if the implementation has already compiled
> bar, then the (compile 'bar) is a noop).  If you instead insert
> a (compile 'bar) after the second foo definition, then the results
> depend on whether the implementation is always compiling as its
> way of interpreting.

>> So surely a very clever compiler is allowed to also return 2.  Yes?

> No. A compile cleverly _placed_ is allowed to return 2.

I still wonder about this, though.  I appreciate that returning 1 is the
most likely outcome, and is suggested by the spec.  But is it really
prohibited for a conforming implementation to automatically recompile
BAR when (= just after) the second defmacro of foo occurs?

You're telling me that portable code can rely on the fact that the
(second) sequence above _must_ return 1?

That would seem to be too bad, because it would prohibit an interesting
design of a future implementation.  I looked up 3.2.2.3 and DEFMACRO, but
of course it's hard to find the language that I'm searching for.  Perhaps
there is something generic in the spec that says an implementation isn't
allowed to (re-)compile functions unless the user requests it?  Although
that doesn't seem quite true either, since implementations are allowed to
compile every form as soon as it is typed into the REPL.

So what in the spec stops my hypothetical implementation from recompiling
bar when then second defmacro occurs?

> CL-USER(1): (shell "cat foo.cl")
> (defmacro foo () 1)
> (eval-when (compile load eval)
>   (defun bar () (foo)))
> (defmacro foo () 2)
> (print (bar))
> (eval-when (compile)
>   (print (bar)))
> CL-USER(2): (compile-file "foo.cl")
> 2 
> CL-USER(3): (load "foo.fasl")
> 1 
> We find the late-binding behavior.  I am hoping that anyone who has
> been following this thread (and understanding it :-) can tell me
> why at compile-time 2 is printed, and at load-time 1 is printed?

Here's a guess: When the compiler is running, it keeps an interpreted version
of BAR around, and thus the final
        (eval-when (compile) (print (bar)))
(which we see first in the run above) runs interpreted, and accesses the late
binding (in the compiler environment) of FOO as 2.  But, prior to that, the
compiler actually compiled BAR into foo.fasl, when that occurred, only the
first defmacro had been seen so far.  So the compiled code that got written
to foo.fasl used a FOO of 1.  Hence 1 gets printed by the first (print (bar))
when you load foo.fasl.

Is that roughly the situation?

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
The philosophy exam was a piece of cake---which was a bit of a surprise,
actually, because I was expecting some questions on a sheet of paper.
From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <4r7knahvm.fsf@franz.com>
Don Geddis <···@geddis.org> writes:

> Duane Rettig <·····@franz.com> wrote on 13 Jan 2005 11:1:
> >> Obviously, a user of portable code couldn't rely on this.  But I wonder
> >> whether something in the spec requires this sequence:
> >>         (defmacro foo () 1)
> >>         (defun bar () (foo))
> >>         (defmacro foo () 2)
> >>         (bar)
> >> to return 1 instead of 2 when compiled.
> >
> > The key phrase is "when compiled", so the real question is:
> > when did you compile bar?  See 3.2.2.3, first paragraph.
> > If you insert a (compile 'bar) right after the defun of bar,
> 
> Excellent point.  So we should consider this code instead:
>         (defmacro foo () 1)
>         (defun bar () (foo))
>         (compile 'bar)
>         (defmacro foo () 2)
>         (bar)
> typed into the REPL.
> 
> > then that paragraph applies, and the call to bar is required
> > to return 1.  (note that if the implementation has already compiled
> > bar, then the (compile 'bar) is a noop).  If you instead insert
> > a (compile 'bar) after the second foo definition, then the results
> > depend on whether the implementation is always compiling as its
> > way of interpreting.
> 
> >> So surely a very clever compiler is allowed to also return 2.  Yes?
> 
> > No. A compile cleverly _placed_ is allowed to return 2.
> 
> I still wonder about this, though.  I appreciate that returning 1 is the
> most likely outcome, and is suggested by the spec.  But is it really
> prohibited for a conforming implementation to automatically recompile
> BAR when (= just after) the second defmacro of foo occurs?

I'm not sure.  There certainly are strong wordings in 3.2.2.3 regarding
redefinition in a compile-file situation, but not necessarily with
macros, and not at all when the forms are typed at top-level.

> You're telling me that portable code can rely on the fact that the
> (second) sequence above _must_ return 1?

I wouldn't rely on it, actually.  Although it is not portable, any
multiprocessing lisp might get a sequence break and the user redefine
bar in a separate thread.  But of course, that is one of the issues
with mulitprocessing, and not with the spec.

However, very little is said in the spec about redefinition; I believe
that, like GC, redefinition is "a given", and the spec mostly calls
out places where such redefinition would be illegal.

I don't know how Screamer (which does recompilations similarly to what
you suggest) handles forms in files, as opposed to top level forms.
If it can get around the restriction against multiply defined functions
in a file, then it might be a good example to look at for some answers
along these lines.  Furthermore, although Screamer might not qualify
as a "conforming implementation", it is definitely portable to many
versions of CL, so Screamer programs are thus themselves portable.

> That would seem to be too bad, because it would prohibit an interesting
> design of a future implementation.  I looked up 3.2.2.3 and DEFMACRO, but
> of course it's hard to find the language that I'm searching for.  Perhaps
> there is something generic in the spec that says an implementation isn't
> allowed to (re-)compile functions unless the user requests it?  Although
> that doesn't seem quite true either, since implementations are allowed to
> compile every form as soon as it is typed into the REPL.

Perhaps you should experiment with Screamer to see if it meets your
definition of the future implementation you speak of.

> So what in the spec stops my hypothetical implementation from recompiling
> bar when then second defmacro occurs?

None that I know of.

> > CL-USER(1): (shell "cat foo.cl")
> > (defmacro foo () 1)
> > (eval-when (compile load eval)
> >   (defun bar () (foo)))
> > (defmacro foo () 2)
> > (print (bar))
> > (eval-when (compile)
> >   (print (bar)))
> > CL-USER(2): (compile-file "foo.cl")
> > 2 
> > CL-USER(3): (load "foo.fasl")
> > 1 
> > We find the late-binding behavior.  I am hoping that anyone who has
> > been following this thread (and understanding it :-) can tell me
> > why at compile-time 2 is printed, and at load-time 1 is printed?
> 
> Here's a guess: When the compiler is running, it keeps an interpreted version
> of BAR around, and thus the final
>         (eval-when (compile) (print (bar)))
> (which we see first in the run above) runs interpreted, and accesses the late
> binding (in the compiler environment) of FOO as 2.  But, prior to that, the
> compiler actually compiled BAR into foo.fasl, when that occurred, only the
> first defmacro had been seen so far.  So the compiled code that got written
> to foo.fasl used a FOO of 1.  Hence 1 gets printed by the first (print (bar))
> when you load foo.fasl.
> 
> Is that roughly the situation?

Smoothly.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Peter Seibel
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <m38y6v7qj2.fsf@javamonkey.com>
Don Geddis <···@geddis.org> writes:

> Excellent point.  So we should consider this code instead:
>         (defmacro foo () 1)
>         (defun bar () (foo))
>         (compile 'bar)
>         (defmacro foo () 2)
>         (bar)
> typed into the REPL.

> I still wonder about this, though.  I appreciate that returning 1 is the
> most likely outcome, and is suggested by the spec.  But is it really
> prohibited for a conforming implementation to automatically recompile
> BAR when (= just after) the second defmacro of foo occurs?
>
> You're telling me that portable code can rely on the fact that the
> (second) sequence above _must_ return 1?

I'd say yes, because the semantics of COMPILE are defined to, at the
very least, expand all macros. Why define those semantics if the
implementation may or may not just undo and redo the compilation
later. I think asking why the implementation can't recompile BAR to
reflect the new definition of FOO is like asking whether it'd be okay
for this sequence:

  (defparameter *foo* 1)

  (defparameter *bar* *foo*)

  (defparameter *foo* 2)

  *bar*

to return 2. Is there something in the standard that explicitly states
that Lisp isn't allowed to infer that you really want *bar* to be
equal to *foo* and thus if *foo* changes *bar* should too. Not that I
know of. But the rules for evaluating forms and the semantics of
DEFPARAMETER rule it out. I'd say the same kind of argument, applied
to COMPILE rules out your example returning 2.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Bourguignon
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87oefr94cm.fsf@thalassa.informatimago.com>
Don Geddis <···@geddis.org> writes:

> Duane Rettig <·····@franz.com> wrote on 13 Jan 2005 11:1:
> >> Obviously, a user of portable code couldn't rely on this.  But I wonder
> >> whether something in the spec requires this sequence:
> >>         (defmacro foo () 1)
> >>         (defun bar () (foo))
> >>         (defmacro foo () 2)
> >>         (bar)
> >> to return 1 instead of 2 when compiled.
> >
> > The key phrase is "when compiled", so the real question is:
> > when did you compile bar?  See 3.2.2.3, first paragraph.
> > If you insert a (compile 'bar) right after the defun of bar,
> 
> Excellent point.  So we should consider this code instead:
>         (defmacro foo () 1)
>         (defun bar () (foo))
>         (compile 'bar)
>         (defmacro foo () 2)
>         (bar)
> typed into the REPL.
> 
> > then that paragraph applies, and the call to bar is required
> > to return 1.  (note that if the implementation has already compiled
> > bar, then the (compile 'bar) is a noop).  If you instead insert
> > a (compile 'bar) after the second foo definition, then the results
> > depend on whether the implementation is always compiling as its
> > way of interpreting.
> 
> >> So surely a very clever compiler is allowed to also return 2.  Yes?
> 
> > No. A compile cleverly _placed_ is allowed to return 2.
> 
> I still wonder about this, though.  I appreciate that returning 1 is the
> most likely outcome, and is suggested by the spec.  But is it really
> prohibited for a conforming implementation to automatically recompile
> BAR when (= just after) the second defmacro of foo occurs?

It's worse. Even without a clever implementation, if you explicitely
compile it again:

         (defmacro foo () 1)
         (defun bar () (foo))
         (compile 'bar)
         (defmacro foo () 2)
         (compile 'bar)
         (bar)

you could still get 1 (or perhaps 2?):

http://www.lispworks.com/reference/HyperSpec/Body/f_cmp.htm
COMPILE:

    If the definition is already a compiled function, compile either
    produces that function itself (i.e., is an identity operation) or
    an equivalent function.

Assuming that by "equivalent function" CLHS actually means a function
recompiled from the original source, redoing the macro expansion time
you could get 2.

Otherwise, if "equivalent function" means equivalent function, then it
would always return 1 until you run again (defun bar ...) or you use
    
    (compile 'bar '(lambda () (foo)))


> You're telling me that portable code can rely on the fact that the
> (second) sequence above _must_ return 1?

It depends on what they mean by "equivalent function".

I think they mean: yes, you can rely on the fact that it _must_ return 1.


Note that COMPILE  is specified to do only the macro expansion as
minimum compilation.

    compilation environment n. 1. An environment that represents
    information known by the compiler about a form that is being
    compiled. See Section 3.2.1 (Compiler Terminology).

This does not include the future of the environment. Only the
environment _while_ _the_ _form_ _is_ _being_ _compiled_.


So, my understand is that:

         (defmacro foo () 1)
         (defun bar () (foo))
         (defmacro foo () 2)
         (compile 'bar)
         (bar)

Should always return 2.



         (defmacro foo () 1)
         (defun bar () (foo))
         (compile 'bar)
         (defmacro foo () 2)
         (bar)

Should always return 1.


         (defmacro foo () 1)
         (defun bar () (foo))
         (compile 'bar)
         (defmacro foo () 2)
         (compile 'bar)
         (bar)

Should always return 1.


         (defmacro foo () 1)
         (defun bar () (foo))
         (defmacro foo () 2)
         (bar)

You could get 1 or 2 depending on whether you have a compiler or an
interpreter and whether macroexpansion time is done at defun or at
execution.


So to get what you want, you don't need smart implementation, you need
an interpreter who does the macro expansion time at run-time, and
avoid COMPILE.  Why do you think I use clisp?


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Don Geddis
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87651zc1d3.fsf@sidious.geddis.org>
You know, to make my example even more interesting, I'm curious about
redefining functions as macros.  Now, this sequence:
        (defun foo () 1)
        (defun bar () (foo))
        (compile 'bar)
        (defun foo () 2)
        (bar)
returns 2.  We all know about function redefinition.

How about this one?
        (defun foo () 1)
        (defun bar () (foo))
        (compile 'bar)
        (defmacro foo () 2)
        (bar)
Likely most implementations throw an error (CMUCL, Allegro CL), or perhaps
return 1, on this sequence.  But is a conforming implementation allowed to
return 2?

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
We must respect the other fellow's religion, but only in the sense and to the
extent that we respect his theory that his wife is beautiful and his children
smart.  -- H.L. Mencken (1880-1956)
From: Pascal Bourguignon
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <877jmhb1wj.fsf@thalassa.informatimago.com>
Don Geddis <···@geddis.org> writes:
> Is there anything from stopping a conforming implementation from
> remembering all the cross references and undefined calls, and then
> silently and automatically re-compiling all dependent functions if you
> ever redefined a macro (or defined a macro for the first time that
> was either undefined or previously defined as a function)?
> 
> Obviously, a user of portable code couldn't rely on this.  But I wonder
> whether something in the spec requires this sequence:
>         (defmacro foo () 1)
>         (defun bar () (foo))
>         (defmacro foo () 2)
>         (bar)
> to return 1 instead of 2 when compiled.  It seems probably not, since you're
> saying (if I understand you correctly) that Allegro will return 2 when
> typed into the REPL, by virtue of "late binding".  And the CL spec tries
> really hard to make interpreters and compilers have the same semantics.

I would not say "really hard". It just tries. Perhaps harder than
previous lisps, but only slightly.


> So surely a very clever compiler is allowed to also return 2.  Yes?

Yes. The result is implementation dependant, it can be 1 or 2,
depending on when the macro expansion time is placed. Even an
interpreter could return 1, if it chooses to do the macro expansion at
DEFUN time.


Now, the question is, since you can't count on one result or the
other, why would you want to write such a random code?  

-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: David Steuber
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87acrdqeee.fsf@david-steuber.com>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Now, the question is, since you can't count on one result or the
> other, why would you want to write such a random code?  

I expect this is another pitfall to trap inexperienced users who are
not thinking along those lines.  I find myself not wanting to use
macros or functions before I've defined them in the file.  I assume
the compiler is not all that bright and won't know what to do with
something that it has not seen yet.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Thomas A. Russ
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <ymism543lir.fsf@sevak.isi.edu>
David Steuber <·····@david-steuber.com> writes:

> 
> Pascal Bourguignon <····@mouse-potato.com> writes:
> 
> > Now, the question is, since you can't count on one result or the
> > other, why would you want to write such a random code?  
> 
> I expect this is another pitfall to trap inexperienced users who are
> not thinking along those lines.  I find myself not wanting to use
> macros or functions before I've defined them in the file.  I assume
> the compiler is not all that bright and won't know what to do with
> something that it has not seen yet.

Well, that's certainly true for Macros, but not for functions.
Since there is a need to handle the indirection for redefined
functions, it is safe to have undefined functions referenced.

In fact, if this were not possible, then mutually recursive
functions would require some type of forward declaration of their
"signature" in order to work properly.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: David Steuber
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87ekgnln5j.fsf@david-steuber.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> David Steuber <·····@david-steuber.com> writes:
> 
> > 
> > Pascal Bourguignon <····@mouse-potato.com> writes:
> > 
> > > Now, the question is, since you can't count on one result or the
> > > other, why would you want to write such a random code?  
> > 
> > I expect this is another pitfall to trap inexperienced users who are
> > not thinking along those lines.  I find myself not wanting to use
> > macros or functions before I've defined them in the file.  I assume
> > the compiler is not all that bright and won't know what to do with
> > something that it has not seen yet.
> 
> Well, that's certainly true for Macros, but not for functions.
> Since there is a need to handle the indirection for redefined
> functions, it is safe to have undefined functions referenced.
> 
> In fact, if this were not possible, then mutually recursive
> functions would require some type of forward declaration of their
> "signature" in order to work properly.

C++ requires function declarations.  Perhaps this is where my habit
comes from.  I can see why it's not necessary to define functions
ahead of use now.  Of course function calls and macro calls look the
same to me.

One thing I have to do when writing a macro is remind myself that it
expands at compile time, not run time.  It's the age old question of
what does it know and when does it know it.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <4is5zad8y.fsf@franz.com>
David Steuber <·····@david-steuber.com> writes:

> ···@sevak.isi.edu (Thomas A. Russ) writes:
> 
> > David Steuber <·····@david-steuber.com> writes:
> > 
> > > 
> > > Pascal Bourguignon <····@mouse-potato.com> writes:
> > > 
> > > > Now, the question is, since you can't count on one result or the
> > > > other, why would you want to write such a random code?  
> > > 
> > > I expect this is another pitfall to trap inexperienced users who are
> > > not thinking along those lines.  I find myself not wanting to use
> > > macros or functions before I've defined them in the file.  I assume
> > > the compiler is not all that bright and won't know what to do with
> > > something that it has not seen yet.
> > 
> > Well, that's certainly true for Macros, but not for functions.
> > Since there is a need to handle the indirection for redefined
> > functions, it is safe to have undefined functions referenced.
> > 
> > In fact, if this were not possible, then mutually recursive
> > functions would require some type of forward declaration of their
> > "signature" in order to work properly.
> 
> C++ requires function declarations.  Perhaps this is where my habit
> comes from.  I can see why it's not necessary to define functions
> ahead of use now.  Of course function calls and macro calls look the
> same to me.

The beauty of Lisp...

> One thing I have to do when writing a macro is remind myself that it
> expands at compile time, not run time.  It's the age old question of
> what does it know and when does it know it.

No, a macro expands at macroexpand time.  Compile time includes a
macroexpand time, and eval on an interpreted form includes a macroexpand
time.  Your statement would have been correct if it had been limited
to talking about compiled forms (you probably _were_ thinking about
compiled forms, but you didn't say so).  But at any rate you should
always consider when you write a macro what it might do in an
interpreted situation.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: David Steuber
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <871xcm4lgd.fsf@david-steuber.com>
Duane Rettig <·····@franz.com> writes:

> David Steuber <·····@david-steuber.com> writes:
> 
> > One thing I have to do when writing a macro is remind myself that it
> > expands at compile time, not run time.  It's the age old question of
> > what does it know and when does it know it.
> 
> No, a macro expands at macroexpand time.  Compile time includes a
> macroexpand time, and eval on an interpreted form includes a macroexpand
> time.  Your statement would have been correct if it had been limited
> to talking about compiled forms (you probably _were_ thinking about
> compiled forms, but you didn't say so).  But at any rate you should
> always consider when you write a macro what it might do in an
> interpreted situation.

You're right.  I was thinking about compiled forms.

I thought interpreted Lisp was supposed to behave the same as compiled
Lisp.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Duane Rettig
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <44qhi33de.fsf@franz.com>
David Steuber <·····@david-steuber.com> writes:

> Duane Rettig <·····@franz.com> writes:
> 
> > David Steuber <·····@david-steuber.com> writes:
> > 
> > > One thing I have to do when writing a macro is remind myself that it
> > > expands at compile time, not run time.  It's the age old question of
> > > what does it know and when does it know it.
> > 
> > No, a macro expands at macroexpand time.  Compile time includes a
> > macroexpand time, and eval on an interpreted form includes a macroexpand
> > time.  Your statement would have been correct if it had been limited
> > to talking about compiled forms (you probably _were_ thinking about
> > compiled forms, but you didn't say so).  But at any rate you should
> > always consider when you write a macro what it might do in an
> > interpreted situation.
> 
> You're right.  I was thinking about compiled forms.
> 
> I thought interpreted Lisp was supposed to behave the same as compiled
> Lisp.

No.  That's why minimal compilation and semanic constraints are
specified on compiled code; it creates a reasonable balance
between compiled and interpreted code.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Don Geddis
Subject: Re: Requirement to define macros before use in interpreted code?
Date: 
Message-ID: <87ekgnc2td.fsf@sidious.geddis.org>
I wrote:
>>         (defmacro foo () 1)
>>         (defun bar () (foo))
>>         (defmacro foo () 2)
>>         (bar)
>> So surely a very clever compiler is allowed to also return 2.  Yes?

Pascal Bourguignon <····@mouse-potato.com> wrote on 13 Jan 2005 19:4:
> Yes. The result is implementation dependant, it can be 1 or 2,
> depending on when the macro expansion time is placed. Even an
> interpreter could return 1, if it chooses to do the macro expansion at
> DEFUN time.

Right, it depends when the compilation actually happens.  So let me force
a time:
        (defmacro foo () 1)
        (defun bar () (foo))
        (compile 'bar)
        (defmacro foo () 2)
        (bar)
Now I wonder whether a conforming implementation is allowed to return 2.

> Now, the question is, since you can't count on one result or the
> other, why would you want to write such a random code?  

Because such a sequence may be convenient when developing code, as part
of rapid prototyping.  Such code shouldn't be present in final source code,
but in the middle of development I can easily see such a macro redefinition.
If a clever implementation was allowed to re-compile bar upon the second
defmacro, then a user of that implementation wouldn't need to be so careful
about keeping track of source code dependencies, and being sure to recompile
all the right files after such a macro change.

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
Sometimes I think I'd be better off dead.  No, wait.  Not me, you.
	-- Deep Thoughts, by Jack Handey [1999]