From: Rainer Joswig on
In article <m2zl2dp33z.fsf(a)gmail.com>,
Helmut Eller <eller.helmut(a)gmail.com> wrote:

> * RG [2010-03-12 23:44+0100] writes:
>
> > In article <m2bpetqjof.fsf(a)gmail.com>,
> > Helmut Eller <eller.helmut(a)gmail.com> wrote:
> >
> >> * RG [2010-03-12 22:52+0100] writes:
> >>
> >> > In article <m2y6hxqlxi.fsf(a)gmail.com>,
> >> > Helmut Eller <eller.helmut(a)gmail.com> wrote:
> >> >
> >> >> * Rainer Joswig [2010-03-12 21:12+0100] writes:
> >> >>
> >> >> > From the CLHS page for COMPILE:
> >> >> >
> >> >> > 'if name is a symbol that names a macro, its macro function is updated'
> >> >>
> >> >> The whole sentence is:
> >> >>
> >> >> If a non-nil name is given, then the resulting compiled
> >> >> function replaces the existing function definition of name and the name
> >> >> is
> >> >> returned as the primary value; if name is a symbol that names a macro,
> >> >> its
> >> >> macro function is updated and the name is returned as the primary value.
> >> >>
> >> >> > I would also say that this is clear.
> >> >>
> >> >> Are you saying that those two clauses are mutually exclusive?
> >> >
> >> > Yes, of course. Why would you doubt it? Function bindings and macro
> >> > function bindings for a single symbol are mutually exclusive.
> >>
> >> OK then. That's all I wanted to know.
> >>
> >> >> "update" could also mean "remove the macro binding".
> >> >
> >> > No, it couldn't, because the first clause refers to replacing the
> >> > "existing function definition." The only way there can be an "existing
> >> > function definition" to replace is if it's a function, not a macro.
> >>
> >> Well, to be nitpicking: 1) if the symbol has no function definition the
> >> first clause applies 2) all symbols with a macro definition have a
> >> non-nil fdefinition too.
> >>
> >> Helmut
> >
> > Yes, but the fdefinition of a macro is not a function.
>
> It is in CMUCL.
>
> Helmut

Right, that's implementation dependent.

'fdefinition accesses the current global function definition
named by function-name. The definition may be a function or may
be an object representing a special form or macro. The value
returned by fdefinition when fboundp returns true but the
function-name denotes a macro or special form is not well-defined,
but fdefinition does not signal an error.'

Examples where it is not a function:

CLISP:

[4]> (fdefinition 'with-open-file)
#<MACRO #<COMPILED-FUNCTION WITH-OPEN-FILE>
((STREAM &REST SYSTEM::OPTIONS) &BODY SYSTEM::BODY)>
[5]> (functionp *)
NIL

Genera:

Command: (fdefinition 'with-open-file)
(SPECIAL #<Compiled function WITH-OPEN-FILE Macroexpander 20222713424>)
Command: (functionp *)
NIL

Clozure CL:

? (fdefinition 'with-open-file)
#(7100233775316992 #<Compiled-function WITH-OPEN-FILE Macroexpander #x30000073907F>)
? (functionp *)
NIL

--
http://lispm.dyndns.org/
From: Kaz Kylheku on
On 2010-03-12, Raymond Toy <toy.raymond(a)gmail.com> wrote:
> If FOO is already a macro, what should (compile 'foo ...) do?

It should produce a compiled version of the macro.

A macro is a function which expands a form.

Macros expand faster when they are in, say, machine language rather than
some interpreted list structure.

This is a nice thing in Lisp: when you extend the compiler by
writing macros, their expanders can be compiled, so that in this regard
they are not at a disadvantage compared to code that is already in the
compiler.
From: Vassil Nikolov on

On Fri, 12 Mar 2010 14:27:06 -0500, Raymond Toy <toy.raymond(a)gmail.com> said:

> If FOO is already a macro, what should (compile 'foo ...) do? The CLHS
> says the macro function should be updated, but it's not clear to me what
> it should be updated to.

I (too) think that when

(macro-function 'foo) => true

then

(compile 'foo '(lambda (f e) ...))

does the same as

(setf (macro-function 'foo) (compile nil '(lambda (f e) ...)))

(though not much can portably be done with the E parameter).

For example:

* (defmacro foo (x) `(list 'foo ,x))

FOO
* (macroexpand '(foo bar))

(LIST 'FOO BAR)
T
*
(compile 'foo
'(lambda (f e) (declare (ignore e)) `(cons 'foo ,(second f))))

FOO
NIL
NIL
* (macroexpand '(foo bar))

(CONS 'FOO BAR)
T

---Vassil.


--
No flies need shaving.
From: Vassil Nikolov on

On Fri, 12 Mar 2010 23:21:00 +0100, Rainer Joswig <joswig(a)lisp.de> said:
> ...
> Unfortunately it is unclear what it does with METHODS and
> GENERIC-FUNCTIONS. If the function is a generic function, does
> it also compile all the methods?

I suppose one could argue that it does, because the methods are
parts of the generic function, but one could also wish this was
specified explicitly. (I think this matter touches upon the matter
of anonymous generic functions, e.g. of usage like

(compile nil (generic-function ...))

if GENERIC-FUNCTION was defined.)

> What is also unclear to me is this:

> (compile 'bar123 (lambda (x) x))

> What does it do if BAR123 has no macro and no function definition?
> The spec says that an existing function definition will be replaced,
> but not that it make it a function definition if there is none.

Indeed. As far as I can tell, nothing is specified for this
condition. I suppose there are at least two lines of reasoning:

1. Defining and compiling functions is by far the most frequent
case, therefore the above (again, in the case under consideration)
should behave along the lines of

(compile (defun bar123 (x) x))

2. It is impossible to tell whether the intent is to install a
function definition or a macro definition, therefore an error must
be signalled.

I don't know which one should be chosen. In any case, while a
Common Lisp implementor must resolve all of these matters in one way
or another, a Common Lisp user, I think, can simply avoid the case
when both arguments of COMPILE are non-nil.

---Vassil.


--
No flies need shaving.
From: Pascal Costanza on
On 13/03/2010 18:42, Vassil Nikolov wrote:
>
> On Fri, 12 Mar 2010 23:21:00 +0100, Rainer Joswig<joswig(a)lisp.de> said:
>> ...
>> Unfortunately it is unclear what it does with METHODS and
>> GENERIC-FUNCTIONS. If the function is a generic function, does
>> it also compile all the methods?
>
> I suppose one could argue that it does, because the methods are
> parts of the generic function, but one could also wish this was
> specified explicitly.

It may actually be a bad idea. What you want to see compiled is not the
methods themselves, but the effective methods, and they are only known
once all method definitions are loaded. Typically, compilation of the
effective methods is delayed until generic functions are actually called
(or to some stage in between method loading and generic function
invocation). The important point here is that optimization of generic
functions requires a much more dynamic approach than what plain static
compilation typically gives you.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/