From: aydogan.ozgur on
I was reading peter seibel's lisp book and run into such variable
declarations in a macro.

(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))

why did he put parenthesis around the '&rest names' i checked it in
slime both with and without parenthesis and i always get the same
results. so what was this for?

thanks .
From: Rainer Joswig on
In article
<8e42c2d6-5e65-4ffd-9648-c3f1c60f9989(a)x35g2000hsb.googlegroups.com>,
aydogan.ozgur(a)gmail.com wrote:

> I was reading peter seibel's lisp book and run into such variable
> declarations in a macro.
>
> (defmacro with-gensyms ((&rest names) &body body)
> `(let ,(loop for n in names collect `(,n (gensym)))
> ,@body))
>
> why did he put parenthesis around the '&rest names' i checked it in
> slime both with and without parenthesis and i always get the same
> results. so what was this for?
>
> thanks .


(defun foo (&rest names &body body)

...)

is not allowed in ANSI CL. There can be only one of &body or
&rest at one level. A good CL implementation will complain.

HyperSpec: 'Only one of &body or &rest can be used at any particular level; '



(defun foo1 ((&rest names) &body body)

...)


indicates that names would be a list of names and body
would be a list of code expressions. Like in:

(foo1 (name-1 name-2 name-n)
(do-something name-1)
(do-something name-2)
(do-something name-n))

If you use &body or &rest is mostly a style issue.
With &body you indicate that the variable following
will be bound to some code expressions and this
helps indenting.

(defun foo2 ((&rest names) &rest body)

...)

Then we would write and indent:


(foo2 (name-1 name-2 name-n)
(do-something name-1)
(do-something name-2)
(do-something name-n))

--
http://lispm.dyndns.org/
From: aydogan.ozgur on
On Jun 19, 2:35 pm, Rainer Joswig <jos...(a)lisp.de> wrote:
> In article
> <8e42c2d6-5e65-4ffd-9648-c3f1c60f9...(a)x35g2000hsb.googlegroups.com>,
>
> aydogan.oz...(a)gmail.com wrote:
> > I was reading peter seibel's lisp book and run into such variable
> > declarations in a macro.
>
> > (defmacro with-gensyms ((&rest names) &body body)
> > `(let ,(loop for n in names collect `(,n (gensym)))
> > ,@body))
>
> > why did he put parenthesis around the '&rest names' i checked it in
> > slime both with and without parenthesis and i always get the same
> > results. so what was this for?
>
> > thanks .
>
> (defun foo (&rest names &body body)
>
> ...)
>
> is not allowed in ANSI CL. There can be only one of &body or
> &rest at one level. A good CL implementation will complain.
>
> HyperSpec: 'Only one of &body or &rest can be used at any particular level; '
>
> (defun foo1 ((&rest names) &body body)
>
> ...)
>
> indicates that names would be a list of names and body
> would be a list of code expressions. Like in:
>
> (foo1 (name-1 name-2 name-n)
> (do-something name-1)
> (do-something name-2)
> (do-something name-n))
>
> If you use &body or &rest is mostly a style issue.
> With &body you indicate that the variable following
> will be bound to some code expressions and this
> helps indenting.
>
> (defun foo2 ((&rest names) &rest body)
>
> ...)
>
> Then we would write and indent:
>
> (foo2 (name-1 name-2 name-n)
> (do-something name-1)
> (do-something name-2)
> (do-something name-n))
>
> --http://lispm.dyndns.org/

HI thanks for the answer, I was visition your site yesterday; nice
coincidence :)

I can't define functions in Slime as you showed

(defun foo2 ((&rest names) &rest body)

I take such an error:

FUNCTION: (&REST REST) is not a SYMBOL

so, I think that type of decleration is correct only for macros. but
the point i don't get is that why shouldn't i define above functions

(defmacro foo2 (names &rest body)

instead of:ambigious one:

(defun foo2 ((&rest names) &rest body)

I always get the same results. so, is `indenting` the only reason of
preferring the latter style?-which won't work in Slime anyway :S



From: Rainer Joswig on
In article
<e3792c4a-efab-4e8e-9589-2fad641c20a6(a)w7g2000hsa.googlegroups.com>,
aydogan.ozgur(a)gmail.com wrote:

> On Jun 19, 2:35 pm, Rainer Joswig <jos...(a)lisp.de> wrote:
> > In article
> > <8e42c2d6-5e65-4ffd-9648-c3f1c60f9...(a)x35g2000hsb.googlegroups.com>,
> >
> > aydogan.oz...(a)gmail.com wrote:
> > > I was reading peter seibel's lisp book and run into such variable
> > > declarations in a macro.
> >
> > > (defmacro with-gensyms ((&rest names) &body body)
> > > `(let ,(loop for n in names collect `(,n (gensym)))
> > > ,@body))
> >
> > > why did he put parenthesis around the '&rest names' i checked it in
> > > slime both with and without parenthesis and i always get the same
> > > results. so what was this for?
> >
> > > thanks .
> >
> > (defun foo (&rest names &body body)
> >
> > ...)
> >
> > is not allowed in ANSI CL. There can be only one of &body or
> > &rest at one level. A good CL implementation will complain.
> >
> > HyperSpec: 'Only one of &body or &rest can be used at any particular level; '
> >
> > (defun foo1 ((&rest names) &body body)
> >
> > ...)
> >
> > indicates that names would be a list of names and body
> > would be a list of code expressions. Like in:
> >
> > (foo1 (name-1 name-2 name-n)
> > (do-something name-1)
> > (do-something name-2)
> > (do-something name-n))
> >
> > If you use &body or &rest is mostly a style issue.
> > With &body you indicate that the variable following
> > will be bound to some code expressions and this
> > helps indenting.
> >
> > (defun foo2 ((&rest names) &rest body)
> >
> > ...)

Oops, did I write DEFUN? I meant DEFMACRO.


> >
> > Then we would write and indent:
> >
> > (foo2 (name-1 name-2 name-n)
> > (do-something name-1)
> > (do-something name-2)
> > (do-something name-n))
> >
> > --http://lispm.dyndns.org/
>
> HI thanks for the answer, I was visition your site yesterday; nice
> coincidence :)
>
> I can't define functions in Slime as you showed
>
> (defun foo2 ((&rest names) &rest body)
>
> I take such an error:
>
> FUNCTION: (&REST REST) is not a SYMBOL

See above, I meant DEFMACRO.

>
> so, I think that type of decleration is correct only for macros. but
> the point i don't get is that why shouldn't i define above functions
>
> (defmacro foo2 (names &rest body)
>
> instead of:ambigious one:
>
> (defun foo2 ((&rest names) &rest body)
>
> I always get the same results. so, is `indenting` the only reason of
> preferring the latter style?-which won't work in Slime anyway :S

(defmacro foo2 (names &rest body)
...)

vs.

(defmacro foo3 ((&rest names) &rest body) ...)

In this case names is required to be a list (possibly empty).


You can't write: (foo3 a b c d)

* (macroexpand '(foo3 a b c d))

debugger invoked on a SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR:
error while parsing arguments to DEFMACRO FOO3:
bogus sublist A to satisfy lambda-list (&REST NAMES)

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.

((DEFMACRO FOO3) (FOO3 A B C D) #<unavailable argument>)
0]

--
http://lispm.dyndns.org/
From: aydogan.ozgur on
On Jun 19, 3:08 pm, Rainer Joswig <jos...(a)lisp.de> wrote:
> In article
> <e3792c4a-efab-4e8e-9589-2fad641c2...(a)w7g2000hsa.googlegroups.com>,
>
>
>
> aydogan.oz...(a)gmail.com wrote:
> > On Jun 19, 2:35 pm, Rainer Joswig <jos...(a)lisp.de> wrote:
> > > In article
> > > <8e42c2d6-5e65-4ffd-9648-c3f1c60f9...(a)x35g2000hsb.googlegroups.com>,
>
> > > aydogan.oz...(a)gmail.com wrote:
> > > > I was reading peter seibel's lisp book and run into such variable
> > > > declarations in a macro.
>
> > > > (defmacro with-gensyms ((&rest names) &body body)
> > > > `(let ,(loop for n in names collect `(,n (gensym)))
> > > > ,@body))
>
> > > > why did he put parenthesis around the '&rest names' i checked it in
> > > > slime both with and without parenthesis and i always get the same
> > > > results. so what was this for?
>
> > > > thanks .
>
> > > (defun foo (&rest names &body body)
>
> > > ...)
>
> > > is not allowed in ANSI CL. There can be only one of &body or
> > > &rest at one level. A good CL implementation will complain.
>
> > > HyperSpec: 'Only one of &body or &rest can be used at any particular level; '
>
> > > (defun foo1 ((&rest names) &body body)
>
> > > ...)
>
> > > indicates that names would be a list of names and body
> > > would be a list of code expressions. Like in:
>
> > > (foo1 (name-1 name-2 name-n)
> > > (do-something name-1)
> > > (do-something name-2)
> > > (do-something name-n))
>
> > > If you use &body or &rest is mostly a style issue.
> > > With &body you indicate that the variable following
> > > will be bound to some code expressions and this
> > > helps indenting.
>
> > > (defun foo2 ((&rest names) &rest body)
>
> > > ...)
>
> Oops, did I write DEFUN? I meant DEFMACRO.
>
>
>
>
>
> > > Then we would write and indent:
>
> > > (foo2 (name-1 name-2 name-n)
> > > (do-something name-1)
> > > (do-something name-2)
> > > (do-something name-n))
>
> > > --http://lispm.dyndns.org/
>
> > HI thanks for the answer, I was visition your site yesterday; nice
> > coincidence :)
>
> > I can't define functions in Slime as you showed
>
> > (defun foo2 ((&rest names) &rest body)
>
> > I take such an error:
>
> > FUNCTION: (&REST REST) is not a SYMBOL
>
> See above, I meant DEFMACRO.
>
>
>
> > so, I think that type of decleration is correct only for macros. but
> > the point i don't get is that why shouldn't i define above functions
>
> > (defmacro foo2 (names &rest body)
>
> > instead of:ambigious one:
>
> > (defun foo2 ((&rest names) &rest body)
>
> > I always get the same results. so, is `indenting` the only reason of
> > preferring the latter style?-which won't work in Slime anyway :S
>
> (defmacro foo2 (names &rest body)
> ...)
>
> vs.
>
> (defmacro foo3 ((&rest names) &rest body) ...)
>
> In this case names is required to be a list (possibly empty).
>
> You can't write: (foo3 a b c d)
>
> * (macroexpand '(foo3 a b c d))
>
> debugger invoked on a SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR:
> error while parsing arguments to DEFMACRO FOO3:
> bogus sublist A to satisfy lambda-list (&REST NAMES)
>
> Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
>
> restarts (invokable by number or by possibly-abbreviated name):
> 0: [ABORT] Exit debugger, returning to top level.
>
> ((DEFMACRO FOO3) (FOO3 A B C D) #<unavailable argument>)
> 0]
>
> --http://lispm.dyndns.org/

correction, i meant (defun foo2 ((&rest names) &body body) not (defun
foo2 ((&rest names) &rest body) which i wrote in my previous post.

> (defmacro foo3 ((&rest names) &rest body) ...)
>
> In this case names is required to be a list (possibly empty).

no It doesn't have to according to Slime; here are the results:

CL-USER> (defmacro mac( (&rest rest) &body body)
(print (cons rest 'a))
(print body))
MAC

CL-USER> (defmacro mac2( rest &body body)
(print (cons rest 'a))
(print body))
MAC2



now let's compare the functions:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CL-USER> (mac2 (1 2) + 3 4 5 6 )

((1 2) . A)
(+ 3 4 5 6)
18
CL-USER> (mac (1 2) + 3 4 5 6 )

((1 2) . A)
(+ 3 4 5 6)
18

SAME results
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CL-USER> (mac 1 + 3 4 5 6 )

(1 . A)
(+ 3 4 5 6)
18
CL-USER> (mac2 1 + 3 4 5 6 )

(1 . A)
(+ 3 4 5 6)
18
again SAME results
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CL-USER> (mac 1 2 + 3 4 5 6 )

(1 . A)
(2 + 3 4 5 6)
; Evaluation aborted

CL-USER> (mac2 1 2 + 3 4 5 6 )

(1 . A)
(2 + 3 4 5 6)
; Evaluation aborted

again SAME results, which require "2" to be function but it is not.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
so, why should I prefer this (defmacro mac( (&rest rest) &body
body) ? :S

ps: i might sound to be hard to learn but I really wonder the reasons,
why? thanks for your effort btw.