From: Vladimir V. Zolotych
Subject: (COMPILE-FILE "MACRO")
Date: 
Message-ID: <3A658C23.7F322CEE@eurocom.od.ua>
This is a multi-part message in MIME format.
--------------F8BD21827150E80C6D472D42
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

  Hello,

I've read about READ-EVAL-PRINT top level loop. I'd like to understand
two things: macros and compilation. How they can be described using
REPL (if it is possible at all). From the point of the Lisp system it
seems there is significant difference between normal function (DEFUN)
and macro (DEFMACRO).  My aim is not to go deeply in details, beside
that it is obviously beyond my abilities. I wish to know things enough
to be able use it right, e.g.  macros, compiling.

Excuse my question if you'll decide the subject is obvious. Anyway
compilation and macros are differ much in Lisp against all other
languages I know. So I think some introduction to this undoubtedly
sophisticated topics will be very useful. I'm sure not only to me.

If I have compiled function say FOO, I should recompile it, if it uses
macros. Recompilation unneeded in case FOO uses functions (not
macros).  Why ?

When I (LOAD "FOO.X86F") I see compiler's messages. What work to
itself it found there, in X86F file ?

Another issue. What happens during (COMPILE-FILE "BAR") ? Is REPL
applicable there ? Probably in some modified form. If so I could say,
the compilation results are "side effects". As I already know compiler
may need PACKAGE to intern symbols in, so some top level forms should
be executed to arrange it (which is not the default during compilation
process). Which other things might be required for the compiler ?
Before compilation (or probably the same time) compiler should expand
macros. This was called "macro expansion" time. But beside name I
doesn't now nothing about that. If you think such knowledge is
useful, I'd like to learn more about that.

Probable I could ask in the following words: 'Would you mind to
describe work of the compiler w/o great detail, in rather "top level"
terms ?'

  Thanks in advance

-- 
Vladimir Zolotych                         ······@eurocom.od.ua
--------------F8BD21827150E80C6D472D42
Content-Type: text/x-vcard; charset=us-ascii;
 name="gsmith.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Vladimir V. Zolotych
Content-Disposition: attachment;
 filename="gsmith.vcf"

begin:vcard 
n:Zolotych;Valdimir V.
x-mozilla-html:FALSE
adr:;;;;;;
version:2.1
·····················@eurocom.od.ua
x-mozilla-cpt:;0
fn:Valdimir V. Zolotych
end:vcard

--------------F8BD21827150E80C6D472D42--

From: R Matthew Emerson
Subject: HyperSpec location (was Re: (COMPILE-FILE "MACRO"))
Date: 
Message-ID: <rbsd7dmjiz3.fsf_-_@agrias.lerc.nasa.gov>
Erik Naggum <····@naggum.net> writes:

>   The standard is pretty good in its description of the process.  See the
>   current location of the HyperSpec, which I hope somebody else can tell us
>   both, because right now none of the URLs I used to have work.  Sigh.
>   There's a whole chapter, anyway, called "evaluation and compilation", and
>   it is a good read.  Grab a copy of the HyperSpect to your local machine
>   -- Xanalys's network connectivity has been worse than flakey of late.

There's a mirror of the HyperSpec at the ALU web site:

http://www.alu.org/HyperSpec/FrontMatter/index.html


-- 
Matt Emerson <···@grc.nasa.gov>
Slimy, yet satisfying.
From: Kent M Pitman
Subject: Re: (COMPILE-FILE "MACRO")
Date: 
Message-ID: <sfwsnmiieny.fsf@world.std.com>
"Vladimir V. Zolotych" <······@eurocom.od.ua> writes:

> I've read about READ-EVAL-PRINT top level loop. I'd like to understand
> two things: macros and compilation. How they can be described using
> REPL (if it is possible at all).

You should start to read the language spec.  It will help with this.

You can download it from:

  http://www.xanalys.com/software_tools/reference/HyperSpec/

However, the model of what defmacro does is very simple:

 (defmacro foo ...)

is pretty much the following:

 (eval-when (:compile-toplevel :load-toplevel :execute) ;compile- and runtime
   (defun secret-foo-expander (...) ...)
   (setf (macro-function 'foo) 'secret-foo-expander))

Compiling the file just sets the file up to have a compiled version of the
defun.  Loading the file, either compiled or not, sets up the expander 
for the macro.  The only effect of compiling the file is to make it faster.

> If I have compiled function say FOO, I should recompile it, if it uses
> macros. Recompilation unneeded in case FOO uses functions (not
> macros).  Why ?

The macro file must be loaded before compiling FOO.

If the macro changes, then FOO should be recompiled since the macro expansion
might be different.  If you're using compiled macros, then if the macro 
changes, you should first recompile the macro file and then recompile FOO.

One normally tries to avoid changing macros at runtime if one can help it.
It's not a normal thing to change a macro and need re-compilation while
an application is running.  It's possible.  It's just painful.  And almost
surely bad style.  If you find yourself doing this, ask someone what you
should be doing instead.  You're probably confused about where to use macros
and where not to.  (You might be doing fine, but the odds of a problem are
high.)

> When I (LOAD "FOO.X86F") I see compiler's messages. What work to
> itself it found there, in X86F file ?

I have no idea what an X86F file is.  This is an implementation-specific
file, not a standard part of CL.  (That's not to say it doesn't implement
something standard.)

> Another issue. What happens during (COMPILE-FILE "BAR") ?

Is BAR the macro file or are you just asking in general for any file?


> Is REPL applicable there ?

You have a faulty model of what the REPL is.  Approximately:

 (defun read-eval-print-loop () (loop (print (eval (read)))))

The REPL is an interactive mechanism for processing forms.  It's not the
only way.  When doing a file compilation, the "R" (i.e., READ) still has
to happen, but the "P" (i.e., PRINT) does not.  The file compiler does loop
through forms, reading them, and producing code that would execute them
(half of the "E", or EVAL, process) but it does not actually run those forms.
The loader (usually the LOAD function) executes what the file compiler has
done.  Doing (load (compile-file ...)) is similar to applying the REPL but
without the P.  And also there are some subtle differences because the file
compiler processes form1, form2, form3, ... and then the loader loads 
processedform1, processedform2, procesedform3, whereas if you'd done it
at the REPL, you'd have gotten a processing of form1 plus an execution of
it before looking at form2.  That is, REPL interleaves preparation and
execution of a series of forms, while file compilation first does all of
the preparation in series and then LOAD does all of the execution in series
and this can create different results in some subtle cases.

You really should read the more detailed, more correct descriptions of 
all of this in the Common Lisp HyperSpec for which I gave you the URL above.

> Probably in some modified form. If so I could say,
> the compilation results are "side effects".

They side-effect the file system, but not normally the runtime environment.

Certainly some forms in compilation do side-effect the compile-time 
environment.  And if you are running compile-file at runtime, then that's
the same as saying the file compiler has side-effects.  Usually people
compile files in separate images to avoid that, but sometimes there are
reasons to do a compile-file dynamically at runtime.

> As I already know compiler
> may need PACKAGE to intern symbols in, so some top level forms should
> be executed to arrange it (which is not the default during compilation
> process). Which other things might be required for the compiler ?

Anything for which you do some other computation that needs it.  For
example, if I do:

 (eval-when (:compile-toplevel) (print x))

then there'd bettter be a

 (eval-when (:compile-toplevel) (setq x 3))

or something before it.  That is, you are coming at the problem from the
wrong side.  Don't worry at all about which things need to be done at
compile time.  Mostly things don't.  Packages are an exception because
they support READ.  You'll find out what else needs to be done either because
you use some facility of someone's that tells you in the doc "this has to 
be loaded at compile time" or else because you yourself create the dependency,
and if you're watching you'll know you did.

By far the most common place where you yourself create the dependency is,
IMO, the following:  You write a macro in which you decide you need a helper
function.  The helper fucntion must be present at compile time. e.g.,

 (defmacro keycall (f key val) (list f (intern-keyword key) val))

Here you have used a function INTERN-KEYWORD that doesn't exist.  If this
were a function, you could just put the definition next to it and you'd be
done.  In fact, if you don't use KEYCALL in the same file, that's all you
need to do.  But INTERN-KEYWORD *must* be defined before KEYCALL is 
actually used in code.  So if you use KEYCALL in the same file, as in:

 (defmacro keycall (f key val) (list f (intern-keyword key) val))
 (defun intern-keyword (x) (intern (string x) (find-package "KEYWORD")))
 (defun foo (x) (keycall ...))

You're going to lose because KEYCALL is a macro that will be expanded at
compile time (that means its expander function will be called at compile
time). The support for that expander function must now be loaded.  So 
you have to force that to be present.

 (defmacro keycall (f key val) (list f (intern-keyword key) val))
 (eval-when (:compile-toplevel :load-toplevel :execute)
 (defun intern-keyword (x) (intern (string x) (find-package "KEYWORD")))
 );nehw-lave
 (defun foo (x) (keycall ...))

[Note that normally you indent Lisp code at deeper paren levels, but I and
some others do not do this when it's a defun, since some editor tools only
see defuns and stuff in the zeroth column.  Instead, I usually make a point
of non-standard bracketing, such as I've done above, and I usually make
some annotation about what the stray paren is matching.  People's personal
style on this sometimes differs.]

Note that if you'd done 

 File A:
 [ (defmacro keycall (f key val) (list f (intern-keyword key) val))
 [ (defun intern-keyword (x) (intern (string x) (find-package "KEYWORD")))

 File B:
 [ (defun foo (x) (keycall ...))

You would not need the eval-when because whatever made sure KEYCALL's 
definition was loaded would implicitly also make sure INTERN-KEYWORD's 
definition was loaded.  It's not possible to load only half a file without
more trouble than anyone ever goes to.

> Before compilation (or probably the same time) compiler should expand
> macros. This was called "macro expansion" time. But beside name I
> doesn't now nothing about that.

Look it up MACROEXPAND in the HyperSpec referenced above.


> If you think such knowledge is
> useful, I'd like to learn more about that.
> 
> Probable I could ask in the following words: 'Would you mind to
> describe work of the compiler w/o great detail, in rather "top level"
> terms ?'

It's in the HyperSpec also.  See the section on compilation, and 
particularly on file compilation, though it's worth your understanding
what it means to compile not in a file, too.

Good luck.
From: Vladimir V. Zolotych
Subject: Re: (COMPILE-FILE "MACRO")
Date: 
Message-ID: <3A65B716.D6DDB19A@eurocom.od.ua>
This is a multi-part message in MIME format.
--------------F73F3303B950341ABD2CA111
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Kent M Pitman wrote:
> 
> 
> Is BAR the macro file or are you just asking in general for any file?

I mean any file.

> 
> It's in the HyperSpec also.  See the section on compilation, and
> particularly on file compilation, though it's worth your understanding
> what it means to compile not in a file, too.

I'll certainly read it. You're very kind to give me so detailed
answer. Great  thanks!


-- 
Vladimir Zolotych                         ······@eurocom.od.ua
--------------F73F3303B950341ABD2CA111
Content-Type: text/x-vcard; charset=us-ascii;
 name="gsmith.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Vladimir V. Zolotych
Content-Disposition: attachment;
 filename="gsmith.vcf"

begin:vcard 
n:Zolotych;Valdimir V.
x-mozilla-html:FALSE
adr:;;;;;;
version:2.1
·····················@eurocom.od.ua
x-mozilla-cpt:;0
fn:Valdimir V. Zolotych
end:vcard

--------------F73F3303B950341ABD2CA111--
From: Jochen Schmidt
Subject: Re: (COMPILE-FILE "MACRO") (OT)
Date: 
Message-ID: <944ibu$c46rs$1@ID-22205.news.dfncis.de>
Vladimir V. Zolotych wrote:

> Kent M Pitman wrote:
>> 
>> 
>> Is BAR the macro file or are you just asking in general for any file?
> 
> I mean any file.
> 
>> 
>> It's in the HyperSpec also.  See the section on compilation, and
>> particularly on file compilation, though it's worth your understanding
>> what it means to compile not in a file, too.
> 
> I'll certainly read it. You're very kind to give me so detailed
> answer. Great  thanks!

Yes I' impressed of the helpfullness of the people at c.l.l everytime 
again. I know no other usegroup with such a high level of education and 
politeness. Yes there are sometimes flames too - but most of them are 
caused by people that misuse the help that is offered them.

Regards,
Jochen
From: Paolo Amoroso
Subject: Re: (COMPILE-FILE "MACRO")
Date: 
Message-ID: <+NBlOpP+R4iecIwT4CeBXGbM8c3h@4ax.com>
On Wed, 17 Jan 2001 11:47:13 GMT, Kent M Pitman <······@world.std.com>
wrote:

> "Vladimir V. Zolotych" <······@eurocom.od.ua> writes:
[...]
> > When I (LOAD "FOO.X86F") I see compiler's messages. What work to
> > itself it found there, in X86F file ?
> 
> I have no idea what an X86F file is.  This is an implementation-specific

"x86f" stands for "x86 fasload". It's a file compiled by CMU CL on an x86
architecture.


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/
From: Will Deakin
Subject: Re: (COMPILE-FILE "MACRO")
Date: 
Message-ID: <3A6DB046.8040900@pindar.com>
Paolo Amoroso wrote:

> "x86f" stands for "x86 fasload"
That slips off the tounge like hot gravel...

;)w