From: Paul Foley
Subject: Re: destructuring in DEFMACRO lambda-lists
Date: 
Message-ID: <m2zof7k71a.fsf@mycroft.actrix.gen.nz>
On Tue, 27 Feb 2001 19:48:30 GMT, Barry Margolin wrote:

> In article <···············@mail.dotcom.fr>,
> Eric Marsden  <········@mail.dotcom.fr> wrote:
>> If I understand section 3.4.4.1.2 "Lambda-list-directed Destructuring
>> by Lambda Lists" of the spec correctly, destructuring is allowed in
>> the &body argument of a DEFMACRO lambda-list. For example
>> 
>> ,----
>> | (defmacro with-pg-connection ((con &rest open-args) &body (forms decls))
>> |   `(let ((,con (pg-connect ,@open-args)))
>> |      ,@decls
>> |      (unwind-protect
>> |          (progn ,@forms)
>> |        (when ,con (pg-disconnect ,con)))))
>> `---
>> 
>> CMUCL is the only implementation I have access to which handles this
>> as I expect. CLISP is being changed to support this. ACL accepts the
>> macro definition but complains when it is used, as does GCL. Corman
>> Lisp refuses the defmacro form.
>> 
>> Is this a valid lambda-list? 

No; it (or at least, the meaning you want it to have) is CMU-specific.

Doesn't seem very useful in this case, either -- the only possible
declaration is a type for "con", which the macro presumably already
knows...

> It looks valid, but it seems like a strange thing to do.  Your macro
> definition seems functionally identical to:

> (defmacro with-pg-connection ((con &rest open-args) forms decls)
>   ...)

No; CMUCL can separate out doc-string, declarations, and "real" body
forms, so that if you write

  (with-pg-connection (...)
    (declare (fixnum x))
    (declare (optimize (speed 3) (debug 0)))
    x
    y
    z)

given the above definition, the macro will be expanded with FORMS
bound to '(X Y Z) and DECLS bound to '((DECLARE (FIXNUM X)) (DECLARE
(OPTIMIZE (SPEED 3) (DEBUG 0))))

-- 
For thæm se the his cræft forlætt, se bið fram thæm cræfte forlæten.
                                                                -- Ælfric
(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))

From: Barry Margolin
Subject: Re: destructuring in DEFMACRO lambda-lists
Date: 
Message-ID: <nJ9n6.19$5t5.22697@burlma1-snr2>
In article <··············@mycroft.actrix.gen.nz>,
Paul Foley  <·······@actrix.gen.nz> wrote:
>On Tue, 27 Feb 2001 19:48:30 GMT, Barry Margolin wrote:
>
>> In article <···············@mail.dotcom.fr>,
>> Eric Marsden  <········@mail.dotcom.fr> wrote:
>>> If I understand section 3.4.4.1.2 "Lambda-list-directed Destructuring
>>> by Lambda Lists" of the spec correctly, destructuring is allowed in
>>> the &body argument of a DEFMACRO lambda-list. For example
>>> 
>>> ,----
>>> | (defmacro with-pg-connection ((con &rest open-args) &body (forms decls))
>>> |   `(let ((,con (pg-connect ,@open-args)))
>>> |      ,@decls
>>> |      (unwind-protect
>>> |          (progn ,@forms)
>>> |        (when ,con (pg-disconnect ,con)))))
>>> `---
>>> 
>>> CMUCL is the only implementation I have access to which handles this
>>> as I expect. CLISP is being changed to support this. ACL accepts the
>>> macro definition but complains when it is used, as does GCL. Corman
>>> Lisp refuses the defmacro form.
>>> 
>>> Is this a valid lambda-list? 
>
>No; it (or at least, the meaning you want it to have) is CMU-specific.
>
>Doesn't seem very useful in this case, either -- the only possible
>declaration is a type for "con", which the macro presumably already
>knows...
>
>> It looks valid, but it seems like a strange thing to do.  Your macro
>> definition seems functionally identical to:
>
>> (defmacro with-pg-connection ((con &rest open-args) forms decls)
>>   ...)
>
>No; CMUCL can separate out doc-string, declarations, and "real" body
>forms, so that if you write

>
>  (with-pg-connection (...)
>    (declare (fixnum x))
>    (declare (optimize (speed 3) (debug 0)))
>    x
>    y
>    z)


Unless CMUCL special-cases that use of &body, this shouldn't happen the way
the above code is written.  Are you sure CMUCL doesn't have a function of
its own that pulls out the declarations and doc-string, something like:

(defmacro with-pg-connection ((con &rest open-args) &body body)
  (multiple-value-bind (doc decls forms) (cmucl:parse-body body)
    (declare (ignore doc))
    `(let (,con)
       ,@decls
       (unwind-protect
           (progn (setq ,con (pg-connect ,@open-args))
                  ,@forms)
         (when ,con
           (pg-disconnect ,con))))))

I suppose they could also have their own extension to lambda list syntax,
e.g. &parsed-body, that does it like you say the above does.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Pierre R. Mai
Subject: Re: destructuring in DEFMACRO lambda-lists
Date: 
Message-ID: <87elwieixs.fsf@orion.bln.pmsf.de>
Barry Margolin <······@genuity.net> writes:

> Unless CMUCL special-cases that use of &body, this shouldn't happen the way
> the above code is written.

Yes CMUCL has an incompatible "extension", that automates parsing the
body for declarations, doc-strings and real body forms, i.e.:

* (defmacro demo (bindings &body (body decls))
    `(let ,bindings ,@decls 5 ,@body))

DEMO
* (macroexpand '(demo ((a 5) (b 6)) (declare (fixnum a b)) (+ a b)))

(LET ((A 5) (B 6))
  (DECLARE (FIXNUM A B))
  5
  (+ A B))
T

Maybe this should be flushed in future versions, given that it
conflicts with ANSI-mandated macro destructuring.

> Are you sure CMUCL doesn't have a function of its own that pulls out
> the declarations and doc-string, something like:
> 
> (defmacro with-pg-connection ((con &rest open-args) &body body)
>   (multiple-value-bind (doc decls forms) (cmucl:parse-body body)

Indeed CMU CL has this function, it is called system:parse-body:

PARSE-BODY is an external symbol in the SYSTEM package.
Function: #<Function SYSTEM:PARSE-BODY {10286DB9}>
Function arguments:
  (body environment &optional (doc-string-allowed t))
Function documentation:
  This function is to parse the declarations and doc-string out of the body of
  a defun-like form.  Body is the list of stuff which is to be parsed.
  Environment is ignored.  If Doc-String-Allowed is true, then a doc string
  will be parsed out of the body and returned.  If it is false then a string
  will terminate the search for declarations.  Three values are returned: the
  tail of Body after the declarations and doc strings, a list of declare forms,
  and the doc-string, or NIL if none.
Its defined argument types are:
  (T T &OPTIONAL T)
Its result type is:
  (VALUES LIST LIST (OR BASE-STRING NULL))
On Sunday, 12/3/00 06:22:40 pm [-1] it was compiled from:
target:code/macros.lisp
  Created: Thursday, 11/30/00 11:55:29 pm [-1]
  Comment: $Header: /home/anoncvs/CVS-cmucl/src/code/macros.lisp,v 1.65 2000/10/06 15:19:59 dtc Exp $

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Paul Foley
Subject: Re: destructuring in DEFMACRO lambda-lists
Date: 
Message-ID: <m27l2ak2d1.fsf@mycroft.actrix.gen.nz>
On Wed, 28 Feb 2001 16:31:22 GMT, Barry Margolin wrote:

>                            Are you sure CMUCL doesn't have a function of
> its own that pulls out the declarations and doc-string, something like:

> (defmacro with-pg-connection ((con &rest open-args) &body body)
>   (multiple-value-bind (doc decls forms) (cmucl:parse-body body)

In fact, it has almost exactly that; 

    (multiple-value-bind (forms decls doc) (sys:parse-body body nil)

would work.

> I suppose they could also have their own extension to lambda list syntax,
> e.g. &parsed-body, that does it like you say the above does.

Well, they use &body.  [Seems contrary to the standard, yes.]

-- 
For thæm se the his cræft forlætt, se bið fram thæm cræfte forlæten.
                                                                -- Ælfric
(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))