continuation of V0.8
Bugs in the specs.
I'll concentrate here to the paragraph of the specs and its influence to
my understanding-process.
The challenge of nested macros starts with the desaster of fighting
through the definitions.
i'm collapsing !!!
;;;; ------------------------------------------------------------
;;;; The Challenge of Nested Macros #V0.9 - ilias - 2002-09-17
;;;; ------------------------------------------------------------
--------------------------------------------------------------------
The standard-document states:
http://www.lispworks.com/reference/HyperSpec/Body/02_df.htm
"[...] If the backquote syntax is nested, the innermost backquoted form
should be expanded first. This means that if several commas occur in a
row, the leftmost one belongs to the innermost backquote.[...]"
=> "the *innermost* backquoted form *should be* expanded first"
=> " if several commas occur in a row, the *leftmost* comma belongs to
the *innermost* backquote"
Applying this definition to our abbrev-macro:
(defmacro abbrev (short long) ;
`(defmacro ,short (&rest args)
`(,',long ,@args))) ;
(abbrev df defun)
=> innermost first, left commas first
`(defmacro ,short (&rest args)
(,long ,@args )))
^ .........this evaluates correctly (,',long => ,long
^... here we *would* get an error, as 'args' is not available.
It looks like the definition of backquote is wrong.
--------------------------------------------------------------------
Verifying with evaluations:
(macroexpand-1 '(abbrev df defun))
LispWorks:
=> (DEFMACRO DF (&REST ARGS) (SYSTEM::BQ-LIST* (QUOTE DEFUN) ARGS))
manual 'translation':
(DEFMACRO DF (&REST ARGS) `(,'DEFUN ,@ARGS))
Allegro:
=> (DEFMACRO DF (&REST ARGS) (EXCL::BQ-CONS 'DEFUN ARGS))
manual 'translation':
(DEFMACRO DF (&REST ARGS) `(,'DEFUN ,@ARGS))
We see in the processing of both implementations:
- The *outermost* backquoted form is processed first.
- The innermost backquoted form is processed partially by the outermost
backquote to evaluate the ,',long to ,'DEFUN.
This confirms: The definition of backquote is wrong.
--------------------------------------------------------------------
The clear human understanding (whatever this means, i'm writing now, so
i reduce complexity in my head):
(defmacro abbrev (short long) ;
`(defmacro ,short (&rest args)
`(,',long ,@args))) ;
(abbrev df defun)
Imagine the backquote as an intelligent projectile (BIP), which is fired
over the code due to a call to abbrev.
(defmacro df (&rest args)
----------`--------------> continues next line
^here the BIP evaluates the target (comma) ,short to df
`(,',long ,@args)))
-`-`-`-----`--------
| | | ^here it ignores *one* again, as there is *one* BIP coming
| | ^here it evaluates ,long to defun
| ^here it ignores *one* tartget, as there is another *one* BIP coming
^here the BIP remembers that theres another *one* BIP to come later.
This confirms: The definition of backquote is wrong.
This confirms: Backquote-syntax has social behaviour.
The projectiles count 'how many projectiles will came next' and leave
exactly this no. of targets 'undestroyed', so the later fired
projectiles can hit them.
Notice that each symbol has its own targets.
--------------------------------------------------------------------
Suggested correction:
http://www.lispworks.com/reference/HyperSpec/Body/02_df.htm
"[...] If the backquote syntax is nested, the innermost backquoted form
should be expanded first. This means that if several commas occur in a
row, the leftmost one belongs to the innermost backquote.[...]"
should be corrected to:
If the backquote syntax is nested, the evaluation-process remains as
usual, from left-to-right, so the *outermost* backquoted form should be
expanded first. If several commas occur in a row, the leftmost one
belongs to the innermost backquote.
better: If serveral commas occur in a row, the innermost backquote would
...i cannot articulate.
i think the thing with the gun is clear.
and this is a 0.x document, so i'm free to be a little fuzzy.
--------------------------------------------------------------------
now i'm happy to delete all the rest.
all the confustion: *innermost* => *outermost*
--------------------------------------------------------------------
*please confirm* me the error in the standard-document.
really a desaster this is.
this small detail, placed in sub-conscious destroys all my
understanding-process.
I hope that nobody comes now and says: very fine all that, but you miss
a detail there.
when i write the final document, hopefully people can understand quicker
the nested-macro.
some ideas:
I've dropped the brackets.
This syntax would be easier i think:
(defmacro abbrev (short long) ;
`(defmacro ,short (&rest args)
`( !,long ,@args))) ; ! = don't evaluate.
or better:
(defmacro abbrev (short long) ;
`(defmacro ,short (&rest args)
`( !,long ,!@args))) ; notice: ,!@args
you can recognize immediately in which pass the evaluation happens.
making the 'target'-count mandatory to fit with the backquote-level
gives possibility off error-detection.
i mean, backquote should signal an error, if only *one* comma is in the
second level. so you must place either , or ! - thus minimizing
possibilitie of error.
making e.g 5th level:
`( !!!,!eval-in-2nd-pass !,,,!eval-in-2-3-4-pass ,!!!!eval-in-last-pass)
`( ,!!!eval-in-5th-pass => would signal an error "5th level eval-marker
missing"
thus you correct to
`( ,!!!!eval-in-5th-pass
-
i hope you are not too tired due to my english.
the final document i'll process with spell-check.
does emacs have spell-check???