[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.