Re: silly: "spel" instead of "macro"
- From: jayessay <nospam@xxxxxxx>
- Date: 28 Nov 2005 19:38:35 -0500
"Jeff M." <massung@xxxxxxxxx> writes:
> Your follow-up explained some more things to me. Thank you. My
> understanding is increasing. :-)
>
> However, you did the following as an example:
>
> > (macroexpand '(defun foo (a) :foo-to-you))
> > Nothing is compiled or evaluated here.
>
> How is that the case? The REPL had to read it, and had to evaluate it
Well, strictly speaking, there was something evaluated - the function
form macroexpand with the quoted list as argument. Nothing about the
_macro form_ DEFUN was evaluated or compiled (or executed for that
matter), which was the salient point for the discussion. Also, I am
using the terms "evaluate", "compile", "form", et al. as formally
defined in CLHS - not as popular venacular. Which I believe makes the
most sense given the context. Also, the typical venacular meanings
are pretty fuzzy.
> in order to display some output. True, nothing was compiled, but that
> may only be because your implementation decided not to.
Actually, not quite. First the macroexpand form could have been
compiled, but the macro form could not have.
> Couldn't another implementation decide to compile before executing
> it?
The function form macroexpand, yes, the macro form no. Also the macro
form was not evaluated and thus not executed and this would be true
independent of implementation.
> I think the big misunderstanding came from my use of the work "tokens".
> In my opinion, I could have said "data" or "code".
There are two problems with this:
i) By substituting "data" for "tokens", you can sort of make your
original claim, but it then becomes empty. Why? Because in that case
you can claim that pretty much every program/function/application does
"exactly the same thing" as C/C++ macros. That is all you are saying
in this case is that they all do some sort of input to output
processing. Not particularly enlightening or of much semantic
content.
ii) It discounts the all important parts of _what_ and _how_ the
transformations are done. However that is the key bit as it is this
aspect which when added to something like i) above turns it from a
completely vacuous statement into something meaningful.
Here are a couple more things to note:
The key thing to understanding macros is to realize they are
functions. Closely followed by understanding that they are called at
a special time and how that fits into the overall processing times.
Many times here you will see the claim that macros are functions which
transform input s-expressions to output s-expressions. Strictly
speaking this is not accurate on a couple counts:
1) "s-expression" is not formally defined by the standard - at least I
don't see it in the glossary, where such things should be found,
nor does it appear in the master index. CLTL2 has it indexed under
the FORMAT ~S directive, which seems to fit well with the
traditional meaning: the _readable_ _print_ representation of some
object. Of course, some objects do _not_ have such a
representation.
2) Macros operate on forms, and forms can be any object, not only the
typically thought of case of _compound form_, which is usually what
many people have in mind by "s-expression" in these discussions.
They can also return any object.
For example,
(defclass fooclass ()
((s1 :initarg :s1)))
(defmacro foo (x)
(make-instance 'fooclass :s1 x))
Note that this macro does not produce any "code" (and certainly not
something that could be an s-expression, since in the current state of
affairs, an instance of fooclass does not have a readable print
representation). This macro is defined to return an instance of type
FOOCLASS as its result _at macroexpansion time_.
It's instructive to inspect some results of a few cases involving (or
looking like they involve) this macro:
(inspect `(foo "hi"))
==>
A proper list @ #x773e6c21 with 2 elements
0-> The symbol FOO
1-> A simple-string (2) "hi"
;; Just a quoted list here
(inspect (foo "hi"))
==>
FOOCLASS @ #x7735408a = #<FOOCLASS @ #x7735408a>
0 Class --------> #<STANDARD-CLASS FOOCLASS>
1 S1 -----------> A simple-string (2) "hi"
;; An instance of FOOCLASS
(inspect (foo (make-instance 'fooclass)))
==>
FOOCLASS @ #x77355712 = #<FOOCLASS @ #x77355712>
0 Class --------> #<STANDARD-CLASS FOOCLASS>
1 S1 -----------> (MAKE-INSTANCE ...), a proper list with 2 elements
;; An instance of FOOCLASS. Think about why S1 here _isn't_ an
;; instance of FOOCLASS.
(inspect `(foo ,(make-instance 'fooclass)))
==>
A proper list @ #x773c9839 with 2 elements
0-> The symbol FOO
1-> #<FOOCLASS @ #x7736b0ea>
;; Quoted list, but with the second element evaluated due to the comma
(inspect (macroexpand `(foo ,(make-instance 'fooclass))))
==>
FOOCLASS @ #x7736e602 = #<FOOCLASS @ #x7736e602>
0 Class --------> #<STANDARD-CLASS FOOCLASS>
1 S1 -----------> #<FOOCLASS @ #x7736e5da>
;; An instance of FOOCLASS and now S1 is also an instance of FOOCLASS.
We can force this sort of effect in more "normal" looking calls of foo
with any argument by making a slight change:
(defmacro foo (x)
(make-instance 'fooclass :s1 (eval x)))
(inspect (foo (make-instance 'fooclass)))
==>
FOOCLASS @ #x77377852 = #<FOOCLASS @ #x77377852>
0 Class --------> #<STANDARD-CLASS FOOCLASS>
1 S1 -----------> #<FOOCLASS @ #x7737782a>
While these sort of macros are not nearly as widely useful as the more
typical "code transformers", they are not useless, as they permit the
constuction of "constants" of arbitrary complexity, that may require
_huge_ amounts of processing to compute, which may be saved as part of
a function definition in a fasl output - just like "ordinary"
constants. For example, in some file foo-stuff.cl:
....
(defun some-initializer (...args...)
(let ((the-special-foo (foo ...))
...)
...))
....
In build system somewhere:
;;; NOTE: this will take a looooonnnnnnnnggg time to compile because
;;; FOO is computing the SPECIAL foo here!!
;;;
(compile-file "foo-stuff.cl")
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
.
- References:
- silly: "spel" instead of "macro"
- From: stevenan
- Re: silly: "spel" instead of "macro"
- From: verec
- Re: silly: "spel" instead of "macro"
- From: Jeff M.
- Re: silly: "spel" instead of "macro"
- From: jayessay
- Re: silly: "spel" instead of "macro"
- From: Jeff M.
- Re: silly: "spel" instead of "macro"
- From: jayessay
- Re: silly: "spel" instead of "macro"
- From: Jeff M.
- silly: "spel" instead of "macro"
- Prev by Date: Re: Lispbox and Lisp Toolkit on Windows
- Next by Date: Re: OT to the extreme
- Previous by thread: Re: silly: "spel" instead of "macro"
- Next by thread: Re: silly: "spel" instead of "macro"
- Index(es):
Relevant Pages
|