knowledge-database (beta)

Current group: comp.lang.lisp

a noob question

a noob question  
Michael Beattie
 Re: a noob question  
Tayssir John Gabbour
 Re: a noob question  
Paul F. Dietz
 Re: a noob question  
Michael Beattie
 Re: a noob question  
Pascal Bourguignon
 Re: a noob question  
Bruce Stephens
 Re: a noob question  
Edi Weitz
 Re: a noob question  
Tayssir John Gabbour
 Re: a noob question  
Surendra Singhi
 Re: a noob question  
drewc
From:Michael Beattie
Subject:a noob question
Date:Sun, 23 Jan 2005 17:41:29 -0500
Why is it that some macros or whatever have double parens around them?
Like...

(let ((x 2))) ; this has 2 parens around the x=2 assignment

or

(do ((i 0 (+ i 1))) ; there's 2 parens around the i=0 and the increment
((> i 10) 'done) ; 2 parens around the "end" condition
(print i))

I guess part of the question is "what exactly is the template for the do
or let macro?"



Mike Beattie
From:Tayssir John Gabbour
Subject:Re: a noob question
Date:23 Jan 2005 16:07:12 -0800
Tayssir John Gabbour wrote:
> . (defmacro let- ((&rest inits) &body body)
> . `(let ,(loop for i on inits by #'cddr
> . collect (list (first i) (second i)))
> . ,@body))

Hmm, a nicer version of LET- would be something like:

.. (defmacro let- (inits &body body)
.. "Like LET, except does away with a redundant level of parens.
..
.. The syntax is: let ({pair}*) declaration* form* => result*
.. pair::= var initform
..
.. Unlike LET, no var may be without an initform."
.. (unless (listp inits)
.. (error "let-: init forms need to be within a list. ~S is not a
list." inits))
.. (unless (evenp (length inits))
.. (error "let-: an even number of init forms is needed. Found only
~A forms.~%~S" (length inits) inits))
.. `(let ,(loop for i on inits by #'cddr
.. collect (list (first i) (second i)))
.. ,@body))

Wrestling with Google Groups was a bit frustrating in my last post...
Incidentally, that's why there's all those dots prefixing my code,
since GG won't indent my posts as I wish.


MfG,
Tayssir
From:Paul F. Dietz
Subject:Re: a noob question
Date:Sun, 23 Jan 2005 16:38:48 -0600
Michael Beattie wrote:
> Why is it that some macros or whatever have double parens around them?
> Like...
>
> (let ((x 2))) ; this has 2 parens around the x=2 assignment
>
> or
>
> (do ((i 0 (+ i 1))) ; there's 2 parens around the i=0 and the increment
> ((> i 10) 'done) ; 2 parens around the "end" condition
> (print i))
>
> I guess part of the question is "what exactly is the template for the do
> or let macro?"

Because these can have more than one binding.

(let ((x 1) (y 2)) (+ x y)) ==> 3

The end condition of DO is grouped with the end form(s), so it doesn't get
confused with the body of the DO.

Paul
From:Michael Beattie
Subject:Re: a noob question
Date:Sun, 23 Jan 2005 18:25:54 -0500
Paul F. Dietz wrote:
> Michael Beattie wrote:
>
>> Why is it that some macros or whatever have double parens around them?
>> Like...
>>
>> (let ((x 2))) ; this has 2 parens around the x=2 assignment
>>
>> or
>>
>> (do ((i 0 (+ i 1))) ; there's 2 parens around the i=0 and the increment
>> ((> i 10) 'done) ; 2 parens around the "end" condition
>> (print i))
>>
>> I guess part of the question is "what exactly is the template for the
>> do or let macro?"
>
>
> Because these can have more than one binding.
>
> (let ((x 1) (y 2)) (+ x y)) ==> 3
>
> The end condition of DO is grouped with the end form(s), so it doesn't get
> confused with the body of the DO.
>
> Paul

Sure, but you can have more than one grouping as such:

(let (x 1) (y 2)) (+ x y)

though that isnt going to work since x and y wont exist outside of that
last paren I guess... It makes sense to me, but it just seems odd...
like why wouldnt it try to evaluate that (x 1) which is invalid in itself.

Maybe I am just thinking too much.

As for the do... I think it's weird that it would take 3 arguments,
where the first one is actually 3 arguments, and the second one is like
2 or whatever and then the last one is the body. I would think it more
intuitive to be like:

(do (i 1 (+ i 1) (> i 10) 'done) (print i))
From:Pascal Bourguignon
Subject:Re: a noob question
Date:24 Jan 2005 01:02:43 +0100
Michael Beattie writes:

> Paul F. Dietz wrote:
> > Michael Beattie wrote:
> >
> >> Why is it that some macros or whatever have double parens around
> >> them? Like...
> >>
> >> (let ((x 2))) ; this has 2 parens around the x=2 assignment
> >>
> >> or
> >>
> >> (do ((i 0 (+ i 1))) ; there's 2 parens around the i=0 and the increment
> >> ((> i 10) 'done) ; 2 parens around the "end" condition
> >> (print i))
> >>
> >> I guess part of the question is "what exactly is the template for
> >> the do or let macro?"

Read the reference: CLHS
http://www.lispworks.com/reference/HyperSpec/Body/s_let_l.htm
http://www.lispworks.com/reference/HyperSpec/Body/m_do_do.htm


You must not think "parenthesis"
(there is absolutely NO parenthesis in lisp!),
but _lists_.


Ok, I hear you people not believing me that there's no parenthesis in
lisp. Try this:

(defun dump-p (p &optional (level ""))
(if (atom p)
(format t "~AATOM: ~A~%" level p)
(progn (format t "~ALIST:~%" level)
(mapcar (lambda (x) (dump-p x (concatenate 'string level " ")))
p))))

[2]> (dump-p '(if (zerop x) 1 (1- x)))

LIST:
ATOM: IF
LIST:
ATOM: ZEROP
ATOM: X
ATOM: 1
LIST:
ATOM: 1-
ATOM: X

Where are the parentheses?

Or try this:

[47]> (com.informatimago.common-lisp.cons-to-ascii:draw-list '(if (zerop x) 1 (1- x)))

+-----------------------------------------------------------+
| |
| |
| +---+---+ +---+---+ +---+---+ +---+---+ |
| | * | * |-->| * | * |-->| * | * |-->| * |NIL| |
| +---+---+ +---+---+ +---+---+ +---+---+ |
| | | | | |
| v | v v |
| +----+ | +---+ +---+---+ +---+---+ |
| | IF | | | 1 | | * | * |-->| * |NIL| |
| +----+ | +---+ +---+---+ +---+---+ |
| | | | |
| | v v |
| | +----+ +---+ |
| | | 1- | | X | |
| | +----+ +---+ |
| v |
| +---+---+ +---+---+ |
| | * | * |-->| * |NIL| |
| +---+---+ +---+---+ |
| | | |
| v v |
| +-------+ +---+ |
| | ZEROP | | X | |
| +-------+ +---+ |
+-----------------------------------------------------------+

Can you see any parenthesis?



> > Because these can have more than one binding.
> > (let ((x 1) (y 2)) (+ x y)) ==> 3
> > The end condition of DO is grouped with the end form(s), so it
> > doesn't get
> > confused with the body of the DO.
> > Paul
>
> Sure, but you can have more than one grouping as such:
>
> (let (x 1) (y 2)) (+ x y)
>
> though that isnt going to work since x and y wont exist outside of
> that last paren I guess... It makes sense to me, but it just seems
> odd... like why wouldnt it try to evaluate that (x 1) which is invalid
> in itself.
>
> Maybe I am just thinking too much.

Yes you are. Try to parse: (let (f 1) (g (f 1)) (x 1))


> As for the do... I think it's weird that it would take 3 arguments,
> where the first one is actually 3 arguments, and the second one is
> like 2 or whatever and then the last one is the body. I would think
> it more intuitive to be like:
>
> (do (i 1 (+ i 1) (> i 10) 'done) (print i))

How could you write the following loop then?

(defun 2^n (n)
(do ((i 0 (1+ i))
(j 1 (* 2 j)))
((= i n) j)))


--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
From:Bruce Stephens
Subject:Re: a noob question
Date:Sun, 23 Jan 2005 23:41:26 +0000
Michael Beattie writes:

[...]

> Sure, but you can have more than one grouping as such:
>
> (let (x 1) (y 2)) (+ x y)

That would more clearly be written:

(let (x 1) (y 2))
(+ x y)

> though that isnt going to work since x and y wont exist outside of
> that last paren I guess... It makes sense to me, but it just seems
> odd... like why wouldnt it try to evaluate that (x 1) which is
> invalid in itself.

(let (x y) ...)

is valid. I guess let could be hacked such that (x 1) worked, but
then it's only invalid because 1 isn't a symbol, so the idea would
only work for a limited set of things.

[...]
From:Edi Weitz
Subject:Re: a noob question
Date:Sun, 23 Jan 2005 23:50:16 +0100
On Sun, 23 Jan 2005 17:41:29 -0500, Michael Beattie wrote:

> I guess part of the question is "what exactly is the template for
> the do or let macro?"

You know where to find the ANSI spec, don't you?



Edi.

--

Lisp is not dead, it just smells funny.

Real email: (replace (subseq "spamtrap@agharta.de" 5) "edi")
From:Tayssir John Gabbour
Subject:Re: a noob question
Date:23 Jan 2005 15:36:46 -0800
Michael Beattie wrote:
> Why is it that some macros or whatever have double parens around
> them? Like...
>
> (let ((x 2))) ; this has 2 parens around the x=2 assignment
>
> or
>
> (do ((i 0 (+ i 1))) ; there's 2 parens around the i=0 and the
increment
> ((> i 10) 'done) ; 2 parens around the "end" condition
> (print i))
>
> I guess part of the question is "what exactly is the template for
> the do or let macro?"

Good questiron. LET's syntax is:

let ({var | (var [init-form])}*) declaration* form* => result*

If we did away with having a single "var" without an initform, which is
probably sucky practice anyway, we could do without the multiple
parens:

.. (let (blah 10
.. foo 20
.. bar 30)
.. (+ blah foo bar))

I'm guessing the Ancients didn't think of it, or really liked tacitly
initting stuff to nil. I recall Paul Graham complaining about this once
while talking about Arc. And if you think about it, setf actually is
like this when you're setting multiple things at once.

.. (defmacro let- ((&rest inits) &body body)
.. `(let ,(loop for i on inits by #'cddr
.. collect (list (first i) (second i)))
.. ,@body))


At the prompt:

.. CL-USER> (macroexpand '(let- (blah 10
.. foo 20
.. bar 30)
.. (list blah foo bar)))
..
.. (let ((blah 10)
.. (foo 20)
.. (bar 30))
.. (list blah foo bar))
.. t


MfG,
Tayssir
From:Surendra Singhi
Subject:Re: a noob question
Date:Sun, 23 Jan 2005 21:33:01 -0700
Tayssir John Gabbour wrote:
> At the prompt:
>
> . CL-USER> (macroexpand '(let- (blah 10
> . foo 20
> . bar 30)
> . (list blah foo bar)))
> .
> . (let ((blah 10)
> . (foo 20)
> . (bar 30))
> . (list blah foo bar))
> . t

What if one doesn't wants to intitialise the variables?
Should one be forced to write!!
(blah nil
foo nil
bar nil)

We need a better solution.

--
Surendra Singhi

www.public.asu.edu/~sksinghi/
From:drewc
Subject:Re: a noob question
Date:Mon, 24 Jan 2005 06:52:40 GMT
Surendra Singhi wrote:
> Tayssir John Gabbour wrote:
>
>> At the prompt:
>>
>> . CL-USER> (macroexpand '(let- (blah 10
>> . foo 20
>> . bar 30)
>> . (list blah foo bar)))
>> .
>> . (let ((blah 10)
>> . (foo 20)
>> . (bar 30))
>> . (list blah foo bar))
>> . t
>
>
> What if one doesn't wants to intitialise the variables?
> Should one be forced to write!!
> (blah nil
> foo nil
> bar nil)
>
> We need a better solution.

Isn't that called 'LET' ?

CL-USER> (let (a b c d)
(values a b c d))
NIL
NIL
NIL
NIL
CL-USER>

perhaps i'm confused as to what we are trying to do here. A general let
that does both types of declaration? how would you parse that?

Personally, i prefer the LET- macro to let, as i think we should be
forced to explicitly initialize to nil (or an actual value of the type
the variable will hold so DECLARE and the like will work).

Then again, a couple extra parens don't bother me much.

drewc

>
> --
> Surendra Singhi
>
> www.public.asu.edu/~sksinghi/
   

Copyright © 2006 knowledge-database   -   All rights reserved