[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Is &body REALLY like &rest?
Date: 28 May 86 16:08 PDT
From: Pavel.pa@Xerox.COM
Subject: Is &body REALLY like &rest?
Another in a long series of clarifications of clarifications is
requested.
In CLtL, page 145, it says
``&body This is identical in function to &rest...''
In Guy's clarifications, it says
``145 Extend the syntax of an &body parameter to DEFMACRO to allow
writing
&body (body-var [declarations-var [doc-var]])''
so as to make it easy to call PARSE-BODY.
In CLtL, page 146, it says
``Anywhere in the lambda-list where a parameter name may appear and
where ordinary lambda-list syntax ... does not otherwise allow a list,
a lambda-list may appear in place of the parameter name.''
This allows for destructuring.
Question: Does the following DEFMACRO do destructuring or does it call
PARSE-BODY?
(defmacro foo (&rest (a b c)) (bar a b c))
The real question is whether or not the clarification introduced a
difference in the meanings of &rest and &body. One possible
interpretation is that a list after &rest does destructuring and a list
after &body implies a call to PARSE-BODY.
Which one is right?
I'm the one that suggested this extension to &BODY, so I have some remarks to
make about this...
Before saying anything, let me just remark that all of your excerpts above
are taken from the DEFMACRO section. In normal LAMBDA expressions, &BODY
is not a valid keyword; only &REST is allowed there.
We wouldn't have had both &REST and &BODY if there weren't at least some
reason for them being allowed to differ. The high-level reason for making
the distinction is that some forms, like DEFUN and LET back-indent their
bodies in some editors. eg, DEFUN indents like:
(DEFUN FOO (X Y Z)
(DECLARE (SPECIAL X))
(BAR Y Z))
The way you get things to indent that way on some systems (eg, the Lisp
Machine) is by writing:
(DEFMACRO DEFUN (NAME BVL &BODY FORMS)
...)
If you'd used &REST instead of &BODY, it would have wanted to indent like:
(DEFUN FOO (X Y Z)
(DECLARE (SPECIAL X))
(BAR Y Z))
The case where &BODY is used is in this case where there's going to be
a body. That's distinguished from something like SETQ which has no body.
So you'd write
(DEFMACRO SETQ (&REST PAIRS) ...)
rather than using &BODY to get indentation like:
(SETQ X Y
Z W
Q R)
rather than
(SETQ X Y
Z W
Q R)
Not completely by coincidence, bodies often have declarations in them, and
rest arguments seldom do. As such, there's no reason to suppose that &REST
should continue to be so similar to &BODY since it would generally be
meaningless to want to parse declarations in a SETQ. I'd vote to not let
&REST use these extra arguments.
On the other hand, when I first suggested this, I am pretty sure I suggested
doing
&BODY body-var [declarations-var [doc-var]]
rather than
&BODY (body-var [declarations-var [doc-var]])
since there's no other possible interpretation to variables following the
body variable. Not only is my original version of this extension completely
upward-compatible with existing code (since it doesn't change something that
destructured into something that does something completely different), but
it also allows better syntax for defaulting the declarations and/or doc. eg,
(DEFMACRO DEFUN-SPECIAL
(NAME VARS &BODY FORMS
(DECLARATIONS `((DECLARE (SPECIAL ,@VARS))))
(DOCUMENTATION (GUESS-SOME-DOC NAME)))
...)
might specify how to create default DECLARATIONS and DOCUMENTATION in the
absence of any explicit declarations and documentation.