From: anders
Subject: LET* where to put end ) and way
Date: 
Message-ID: <1185397349.820629.37470@57g2000hsv.googlegroups.com>
I started to look att www.franz.com video introduktion for LISP and
have a seen test program for let*

(let* (( x 0)
       (y ( * 2 3))
        z           )

        (print z)
        (format  t "~% (~a,~a)" x y )))

and i was trying to write a version of hello world using let*
like this

(defun hello ()
  (let* (
	 (USER "Anders")
	 (MESSAGE "Best regards"))
  (format t "~% ~a ~a " MESSAGE USER)))

Both works but in exampel 1 the let* last ) is after z...
But to make exampel 2 work i have to set last ) for let* after format

If not format say USER and MESSAGE is not define.

I can't understand de diffrent, can some one tell me if i make my
samting wrong
or is i a good reason for de diffrens..

// Anders

From: Rainer Joswig
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <joswig-C2D107.23320425072007@news-europe.giganews.com>
In article <·······················@57g2000hsv.googlegroups.com>,
 anders <················@gmail.com> wrote:

> I started to look att www.franz.com video introduktion for LISP and
> have a seen test program for let*
> 
> (let* (( x 0)
>        (y ( * 2 3))
>         z           )
> 
>         (print z)
>         (format  t "~% (~a,~a)" x y )))

There is one parenthesis at the end you might want to delete.

Properly formatted it looks like this:

(let* (( x 0)
       (y ( * 2 3))
       z)
  (print z)
  (format  t "~% (~a,~a)" x y))


> 
> and i was trying to write a version of hello world using let*
> like this
> 
> (defun hello ()
>   (let* (
> 	 (USER "Anders")
> 	 (MESSAGE "Best regards"))
>   (format t "~% ~a ~a " MESSAGE USER)))

You should use the Lisp indenting feature of your
favorite editor.

(defun hello ()
  (let* ((USER "Anders")
         (MESSAGE "Best regards"))
    (format t "~% ~a ~a " MESSAGE USER)))


> 
> Both works but in exampel 1 the let* last ) is after z...
> But to make exampel 2 work i have to set last ) for let* after format

LET* encloses the whole form.

> 
> If not format say USER and MESSAGE is not define.
> 
> I can't understand de diffrent, can some one tell me if i make my
> samting wrong
> or is i a good reason for de diffrens..
> 
> // Anders


Check out the syntax for LET* here:

http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm#letST

-- 
http://lispm.dyndns.org
From: anders
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185400568.687257.160640@l70g2000hse.googlegroups.com>
Thanks.
mvh Anders
From: szergling
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185418356.378542.311080@z24g2000prh.googlegroups.com>
On Jul 26, 9:02 am, anders <················@gmail.com> wrote:
> I started to look attwww.franz.comvideo introduktion for LISP and
> have a seen test program for let*
>
> (let* (( x 0)
>        (y ( * 2 3))
>         z           )
>
>         (print z)
>         (format  t "~% (~a,~a)" x y )))
>
> and i was trying to write a version of hello world using let*
> like this
>
> (defun hello ()
>   (let* (
>          (USER "Anders")
>          (MESSAGE "Best regards"))
>   (format t "~% ~a ~a " MESSAGE USER)))
>
> Both works but in exampel 1 the let* last ) is after z...
> But to make exampel 2 work i have to set last ) for let* after format
>


Think of this

(let* ((x 0)
       (y (* 2 3))
       z)
  (print z)
  (format  t "~% (~a,~a)" x y))

as

(let* ((x 0)
       (y (* 2 3))
       (z nil))
  (print z)
  (format  t "~% (~a,~a)" x y))




Aside:


Sometimes, I wish let had fewer parentheses. Is it really worth it
being succinct with specifying nil? How often does anyone do that? If
we agree to get rid of the "lone symbol gets bound to nil" thing, we
can all write this and be happy.

(let* (x 0
       y (* 2 3)
       z nil)
  (print z)
  (format  t "~% (~a,~a)" x y))


(This suggestion probably cannot be taken seriously by anyone, and I
don't think it's (socially) acceptable to write a slightly different
let for such trivia, so...)
From: Ken Tilton
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <3VVpi.842$Md6.102@newsfe12.lga>
szergling wrote:
> On Jul 26, 9:02 am, anders <················@gmail.com> wrote:
> 
>>I started to look attwww.franz.comvideo introduktion for LISP and
>>have a seen test program for let*
>>
>>(let* (( x 0)
>>       (y ( * 2 3))
>>        z           )
>>
>>        (print z)
>>        (format  t "~% (~a,~a)" x y )))
>>
>>and i was trying to write a version of hello world using let*
>>like this
>>
>>(defun hello ()
>>  (let* (
>>         (USER "Anders")
>>         (MESSAGE "Best regards"))
>>  (format t "~% ~a ~a " MESSAGE USER)))
>>
>>Both works but in exampel 1 the let* last ) is after z...
>>But to make exampel 2 work i have to set last ) for let* after format
>>
> 
> 
> 
> Think of this
> 
> (let* ((x 0)
>        (y (* 2 3))
>        z)
>   (print z)
>   (format  t "~% (~a,~a)" x y))
> 
> as
> 
> (let* ((x 0)
>        (y (* 2 3))
>        (z nil))
>   (print z)
>   (format  t "~% (~a,~a)" x y))
> 
> 
> 
> 
> Aside:
> 
> 
> Sometimes, I wish let had fewer parentheses. Is it really worth it
> being succinct with specifying nil? How often does anyone do that? If
> we agree to get rid of the "lone symbol gets bound to nil" thing, we
> can all write this and be happy.
> 
> (let* (x 0
>        y (* 2 3)
>        z nil)

No, you will be happy, but not for long, because you have not thought 
through all the implications.

kt
From: Kent M Pitman
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <uk5snis81.fsf@nhplace.com>
szergling <···············@gmail.com> writes:

> Sometimes, I wish let had fewer parentheses. Is it really worth it
> being succinct with specifying nil?

IMO, that isn't what it's for.  It's so you can distinctly say, as a
matter of style, that you haven't initialized a variable differently
than saying that you have initialized it to NIL.  In both cases, it
gets NIL.  But use the symbol case when you are saying "I'll give it
the real value later" and use the initial value case when you're
saying "I mean to say that if I don't assign it, you should expect it
to be NIL."  [Some people use (x) and some use x as a way of saying
no initial value, but I doubt you'd get even those groups to agree, 
even though I bet many of them would say they didn't think your fewer
parens idea was good.]

A long time ago, it may well have been about space.  Early Lisp had very
little address space and every cons mattered.  But since then, it has 
evolved to be a style choice.

> How often does anyone do that? 

I do it all the time.

> If we agree to get rid of the "lone symbol gets bound to nil" thing,

Don't hold your breath.

> we can all write this and be happy.

I wouldn't want to write this anyway because it doesn't do grouping.
A thing I do a lot is:

  `(let ,(mapcar #'list vars vals) ...)
 
and similarly the reverse when interpreting variable lists.  All of the
mechanisms for dealing with alternating variables and values in a list
are uglier.

> (let* (x 0
>        y (* 2 3)
>        z nil)
>   (print z)
>   (format  t "~% (~a,~a)" x y))
> 
> 
> (This suggestion probably cannot be taken seriously by anyone, and I
> don't think it's (socially) acceptable to write a slightly different
> let for such trivia, so...)

IMO, the parens are useful and you should work with it.

But if you don't like it, the language gives you all the rope you need
to experiment with your own alternatives.  It requires no one's agreement,
just a tiny amount of code of your own done in private that will bother
no one.

- - - - 

It may be of interest to you to know that there used to be a form of DO
that allowed fewer parens.

I believe it was:
 (do i 0 (+ i 1) (< i 10) ...)
Basically, using an atom in the first position identified that you had
only the simple case.  And I believe no exit clauses.
(There were some other bizarre special cases too.)

This style fell out of favor, I'm not sure why.  Probably because it was
not as general.  But anyway, it was a move toward more parens, not fewer.
I don't know if that shows anything major--but it does show that not 
everyone eschews parens.
From: szergling
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185435290.954774.78720@z24g2000prh.googlegroups.com>
On Jul 26, 6:39 pm, Kent M Pitman <······@nhplace.com> wrote:
> szergling <···············@gmail.com> writes:
> > Sometimes, I wish let had fewer parentheses. Is it really worth it
> > being succinct with specifying nil?
>
> IMO, that isn't what it's for.  It's so you can distinctly say, as a
> matter of style, that you haven't initialized a variable differently
> than saying that you have initialized it to NIL.  In both cases, it
> gets NIL.  But use the symbol case when you are saying "I'll give it
> the real value later" and use the initial value case when you're
> saying "I mean to say that if I don't assign it, you should expect it
> to be NIL."  [Some people use (x) and some use x

Thanks for that tidbit of info. I have not been aware of such idioms
for transmitting programmer intention. In my code, I often do

(let ((a nil) (b nil)) etc)

to be explicit with their being nil. I never really differentiated
between (implicit) nil as meaning <uninitialised> vs nil as
intentional nil.


> A long time ago, it may well have been about space.  Early Lisp had very
> little address space and every cons mattered.  But since then, it has
> evolved to be a style choice.


I was under the impression that the parens had always been there since
the primordial (hand written on paper) lisp, so it was not evolved,
but just a tradition. I doubt I'm the only one who sometimes thought
about this. What about those Schemers with their bracket thingies?

(let ([a 1] [b 2]) ...)

Now, I find that to be worse and just irritating.


>
> I wouldn't want to write this anyway because it doesn't do grouping.
> A thing I do a lot is:
>
>   `(let ,(mapcar #'list vars vals) ...)
>
> and similarly the reverse when interpreting variable lists.  All of the
> mechanisms for dealing with alternating variables and values in a list
> are uglier.

Yes, it is harder to collect binding forms when crafting macros with
the new 'let' in them. However, what about code walkers? You have just
removed one extra alternative clause. Of course, we manually write
macros more than we walk code, so on balance extra parens win out.


> > (This suggestion probably cannot be taken seriously by anyone, and I
> > don't think it's (socially) acceptable to write a slightly different
> > let for such trivia, so...)
>
> IMO, the parens are useful and you should work with it.

And I do work with it :).


I became more aware of my feelings towards 'let' when I saw its
logical consequences. The metabang-bind package has a "steroided" let,
called 'bind' in it, that also does multiple-value-bind, and
destructuring-bind. It has the advantage that we can reduce usage of
the long destructuring-bind and multiple-value-bind names, among other
things. It's parens rule follows logically from let, but now that just
leads to another extra layer on the onion:

(defun test ()
  (values 1 2 3))

Compare

(bind (((values a b c) (test))
       (x 1)
       (y 2)
       (z 3))
 (blah))

against

(bind ((values a b c) (test)
       x 1
       y 2
       z 3)
 (blah))

Or, a power destructuring-bind

(bind ((((a b) c (d e))
        '((1 2) 3 (4 5))))
  ...)

vs

(bind (((a b) c (d e))
       '((1 2) 3 (4 5)))
  ...)

So I'm not sure which ones I like better. But there sure are a lotta
parens. Finally there is one place we already to this -- setf. Imagine
the outcry over:

(setf (a 2))
(setf (a 4) (b 5) (c 6))
(setf ((values a b c) (values 1 2 3))) ;; Argh, my eyes...

It's a totally different situation with setf of course. And yes, my
quibbles
are all academic and is not worth losing sleep over. Ultimately,
nobody
sees the parens anymore anyway, right?
From: Sacha
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <L3_pi.16500$QK3.877769@phobos.telenet-ops.be>
szergling wrote:

> (setf (a 2))
> (setf (a 4) (b 5) (c 6))
> (setf ((values a b c) (values 1 2 3))) ;; Argh, my eyes...
> 
> It's a totally different situation with setf of course. And yes, my
> quibbles
> are all academic and is not worth losing sleep over. Ultimately,
> nobody
> sees the parens anymore anyway, right?
> 

I remember being annoyed on several occasions by the current syntax of setf

(setf a 12
       b 14
       c 13)

How the hell am i supposed to select a logical unit (symbol + its 
binding) in my editor ?
Only for that, I'd rather have it with parens.

Sacha
From: Sacha
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <J8_pi.16507$zU7.757902@phobos.telenet-ops.be>
Sacha wrote:
> szergling wrote:
> 
>> (setf (a 2))
>> (setf (a 4) (b 5) (c 6))
>> (setf ((values a b c) (values 1 2 3))) ;; Argh, my eyes...
>>
>> It's a totally different situation with setf of course. And yes, my
>> quibbles
>> are all academic and is not worth losing sleep over. Ultimately,
>> nobody
>> sees the parens anymore anyway, right?
>>
> 
> I remember being annoyed on several occasions by the current syntax of setf
> 
> (setf a 12
>       b 14
>       c 13)
> 
> How the hell am i supposed to select a logical unit (symbol + its 
> binding) in my editor ?
> Only for that, I'd rather have it with parens.
> 
> Sacha

mhhh of course the simple case

(setf a 12)

makes it a better solution.
I guess i'm bound to write a setf* macro or something =P

Sacha
From: Simon Katz
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <uutga3pgkt6joilv103v3i7tpkekdio415@4ax.com>
On Thu, 26 Jul 2007 09:51:37 GMT, Sacha <····@address.spam> wrote:

>Sacha wrote:
>> I remember being annoyed on several occasions by the current syntax of setf
>> 
>> (setf a 12
>>       b 14
>>       c 13)
>> 
>> How the hell am i supposed to select a logical unit (symbol + its 
>> binding) in my editor ?
>> Only for that, I'd rather have it with parens.
>> 
>> Sacha
>
>mhhh of course the simple case
>
>(setf a 12)
>
>makes it a better solution.
>I guess i'm bound to write a setf* macro or something =P
>
>Sacha

I do this:

(setf a 12)
(setf b 14)
(setf c 13)

It's slightly verbose but I have the "logical units" without the need
for a macro.

Simon

___________________
Real email address:
(substitute ··@ #\+ (substitute #\s #\! "u!enet001+nomi!tech.com"))
From: Kent M Pitman
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <ufy3aixwt.fsf@nhplace.com>
szergling <···············@gmail.com> writes:

> (bind (((values a b c) (test))
>        (x 1)
>        (y 2)
>        (z 3))
>  (blah))
> 
> against
> 
> (bind ((values a b c) (test)
>        x 1
>        y 2
>        z 3)
>  (blah))

Do you know about the control-meta operations in Emacs?
Things like c-m-f and c-m-b and c-m-k and c-m-t don't work well 
with these notations you're wanting to devise, and this is the reason
you'll get much more pushback from people than you expect.

> Ultimately, nobody sees the parens anymore anyway, right?

Not exactly.  Programs see them.  And one of the real strengths of
Lisp notation is the fact that you can programmatically grab an
expression by its paren, pick it up, and move it elsewhere.  This
makes for a lot less mouse motion than in infix languages, where there
is an inherent ambiguity about what expression is denoted by any
operation defined on "the current expression".  (See also the first
question on my slashdot interview for a slightly elaborated
explanation of that issue.)
From: szergling
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185503208.891137.252840@m37g2000prh.googlegroups.com>
On Jul 27, 10:48 am, Kent M Pitman <······@nhplace.com> wrote:
> Do you know about the control-meta operations in Emacs?

Definitely. It's the ultimate language lock in. I cannot program in
any other languages now. How'm I gonna get a non-Lisp job?

> Things like c-m-f and c-m-b and c-m-k and c-m-t don't work well

Ouch. Us new dogs use M-f, M-b, C-k, C-t, with slime+paredit, as is
the fashion :) (Aside: man, why didn't anyone tell me about
slime-reindent-defun, remapped from C-cM-q to M-q, there's just no
need to go up to the top-level defun to indent-sexp!).

> Not exactly.  Programs see them.  And one of the real strengths of
> Lisp notation is the fact that you can programmatically grab an
> expression by its paren, pick it up, and move it elsewhere.  This
> makes for a lot less mouse motion than in infix languages, where there
> is an inherent ambiguity about what expression is denoted by any

Yes. You're quite right. But in this case, unelegant as it is,
kill-sexp becomes C-k C-k (ie twice), so it's not that
bad. transpose-sexp is harder :).

> operation defined on "the current expression".  (See also the first
> question on my slashdot interview for a slightly elaborated
> explanation of that issue.)

Thanks for that. Good read. I read that before I used Lisp, and it all
makes sense now, but back then (pre-conversion), it wasn't that
compelling (being devil's advocate, if you like): why would anyone
want to do all that? Why complicate things (which would be true in
Java) and become dependent on these 'fancy tools' (which they would
have to be, in Java). What's wrong with my arrow-keys in notepad, with
Java? It's not easy converting people... Furthermore, Greenspun is a
powerful equaliser of languages. On a limited scale, those new
intellisense things for .NET seem to understanding program structure,
and can soon probably offer some the tree-traversing commands.

Of course, I have seen the grave errors of my ways. All that time I
wasted, all those precious years (and it's not just me). I think all
you old dogs under-estimate the damage things like the C++ or Java
hype can cause on us impressionable young ones. Life is just too short
not to be coding in Lisp.
From: Matthias Buelow
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <5gt4m7F3ic0tcU1@mid.dfncis.de>
szergling wrote:

> Of course, I have seen the grave errors of my ways. All that time I
> wasted, all those precious years (and it's not just me). I think all
> you old dogs under-estimate the damage things like the C++ or Java
> hype can cause on us impressionable young ones. Life is just too short
> not to be coding in Lisp.

Can't speak for any old dogs but if you ask me, you may stop grovelling
now.. Jesus...

I don't think learning C++ or Java is a waste of time... they're pretty
much standard repertoire today and one ought to be reasonably proficient
in them. At worst, you get some understanding of how not to do certain
things.
From: szergling
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185506932.135152.86070@e16g2000pri.googlegroups.com>
On Jul 27, 2:46 pm, Matthias Buelow <····@incubus.de> wrote:
> I don't think learning C++ or Java is a waste of time... they're pretty

Nope. For *me*, Java was mostly a bloody waste of my youth. For you,
maybe not. I have much better things to do in life than study the
intricacies of compiler bugs or workarounds to languages. For the
things *I* want to do, Lisp has been very good to me.

> much standard repertoire today and one ought to be reasonably proficient

What would be in a standard repertoire? Again, this depends on what
you work in, doesn't it?

> in them. At worst, you get some understanding of how not to do certain
> things.

It's often a lesson that's easier learnt elsewhere though. Sure. It's
great that I can read other people's code.  I'm glad I know more
languages.  But at what cost?  In the time it took to learn those
languages, I could've done much more in other more productive fields
(not just limited to programming), so I'm only just catching up today.
From: Alan Crowe
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <866446c8gm.fsf@cawtech.freeserve.co.uk>
Matthias Buelow <···@incubus.de> writes:
> 
> I don't think learning C++ or Java is a waste of time... they're pretty
> much standard repertoire today and one ought to be reasonably proficient
> in them. At worst, you get some understanding of how not to do certain
> things.

There are too many ways to do things wrong. Learning through
a process of elimination is too slow.

I'm trying to train myself to use to web to seek out the
"how to do things right" pages and ignore the "Don't make
these mistakes" pages. There are too many of the latter.

Alan Crowe
Edinburgh
Scotland
From: Chris Russell
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185438411.799683.208790@22g2000hsm.googlegroups.com>
On 26 Jul, 07:39, Kent M Pitman <······@nhplace.com> wrote:
> szergling <···············@gmail.com> writes:
> > Sometimes, I wish let had fewer parentheses. Is it really worth it
> > being succinct with specifying nil?
>
> IMO, that isn't what it's for.  It's so you can distinctly say, as a
> matter of style, that you haven't initialized a variable differently
> than saying that you have initialized it to NIL.  In both cases, it
> gets NIL.  But use the symbol case when you are saying "I'll give it
> the real value later" and use the initial value case when you're
> saying "I mean to say that if I don't assign it, you should expect it
> to be NIL."  [Some people use (x) and some use x as a way of saying
> no initial value, but I doubt you'd get even those groups to agree,
> even though I bet many of them would say they didn't think your fewer
> parens idea was good.]
>
*Devil's advocate hat on*
You could use nil and '() to make this distinction.

> > we can all write this and be happy.
>
> I wouldn't want to write this anyway because it doesn't do grouping.
> A thing I do a lot is:
>
>   `(let ,(mapcar #'list vars vals) ...)
>
> and similarly the reverse when interpreting variable lists.  All of the
> mechanisms for dealing with alternating variables and values in a list
> are uglier.

Well, with the alternate syntax you'd just write mapcan instead of
mapcar and to go the other way something like:

(do ((list list))
    ((not list))
   (push (pop list) vars)
   (push (pop list) vals)))

which seems acceptable.

setf uses the `new' suggested syntax anyway, and I think that if the
case for using not using this alternate syntax was that strong setf
would look very different.

It looks to me like the choice of syntax just didn't matter that much
for let or setf, and that have people just stuck with what they were
used to.
After all, why break existing code if you don't have too?
From: Matthias Benkard
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <1185446624.770092.313650@w3g2000hsg.googlegroups.com>
Hi,

> You could use nil and '() to make this distinction.

Well...  Except that NIL also means "false" in Lisp, which is rather
often a reasonable initial value.

Mata ne,
Matthias
From: Alan Crowe
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <863azac7kq.fsf@cawtech.freeserve.co.uk>
Kent M Pitman <······@nhplace.com> writes:

> szergling <···············@gmail.com> writes:
> 
> > Sometimes, I wish let had fewer parentheses. Is it really worth it
> > being succinct with specifying nil?
> 
> IMO, that isn't what it's for.  It's so you can distinctly say, as a
> matter of style, that you haven't initialized a variable differently
> than saying that you have initialized it to NIL.  In both cases, it
> gets NIL.  But use the symbol case when you are saying "I'll give it
> the real value later" and use the initial value case when you're
> saying "I mean to say that if I don't assign it, you should expect it
> to be NIL." 

Do you have a strong opinion on initialising stacks? I'm
thinking of this kind of code.

(defun split-into-odd-and-even (list-of-numbers)
  (let ((odd '())
        (even '()))
    (dolist (number list-of-numbers (values odd even))
      (if (oddp number)
          (push number odd)
          (push number even)))))

I want to write (let (odd even)
                  (dolist ...    ))

If the first use of a varible, v, is going to be as the place
for a PUSH should it be (let (v)...) or (let ((v '()))...) ?

I think I want to do what every-one else does so that my
code can be read by others. 

On the other hand, if I'm serious about publishing source,
perhaps I should be polishing up the code before FTPing and
writing

(let (odd even flag)
  (declare (list odd even)
           (boolean flag))
  (dolist ...               ))

Alan Crowe
Edinburgh
Scotland
From: Andrew Philpot
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <slrnfak2tq.rmd.philpot@ubirr.isi.edu>
On 2007-07-27, Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
>
> Do you have a strong opinion on initialising stacks? I'm
> thinking of this kind of code.
>
> (defun split-into-odd-and-even (list-of-numbers)
>   (let ((odd '())
>         (even '()))
>     (dolist (number list-of-numbers (values odd even))
>       (if (oddp number)
>           (push number odd)
>           (push number even)))))
>
> I want to write (let (odd even)
>                   (dolist ...    ))
>
> If the first use of a varible, v, is going to be as the place
> for a PUSH should it be (let (v)...) or (let ((v '()))...) ?
>
> Alan Crowe
> Edinburgh
> Scotland

I think I'm the only one who does this, but I if I'm initializating a
variable which will be mutated (such as a stack) to the empty list, I
typically do

(let ((stack (list)))
  ... mutating code ...
  )

I know that '() and () and NIL and (LIST) all evaluate to the same
thing, but sometimes at a fast glance '() looks like a quoted literal
and () like an empty list and NIL like a boolean false value.  And so
(LIST) to me looks a little more like an object constructor than any
of the rest.  If instead I want to initialize it to a list with (say)
a single element, I'm only changing the arguments, not the core form.

I tell myself that a good compiler's compiler macros can evaluate LIST
with no args without even an O(1) penalty, but even if they can't or
don't, the increase in clarity seems worth it to me.

-- 
Andrew Philpot
USC Information Sciences Institute
·······@isi.edu
From: Alan Crowe
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <86zm1hbsn9.fsf@cawtech.freeserve.co.uk>
Andrew Philpot <·······@isi.edu> writes:

> On 2007-07-27, Alan Crowe <····@cawtech.freeserve.co.uk> wrote:
> >
> > Do you have a strong opinion on initialising stacks? I'm
> > thinking of this kind of code.
> >
> I think I'm the only one who does this, but I if I'm initializating a
> variable which will be mutated (such as a stack) to the empty list, I
> typically do
> 
> (let ((stack (list)))
>   ... mutating code ...
>   )
> 
> I know that '() and () and NIL and (LIST) all evaluate to the same
> thing, but sometimes at a fast glance '() looks like a quoted literal
> and () like an empty list and NIL like a boolean false value.  And so
> (LIST) to me looks a little more like an object constructor than any
> of the rest. 

Wow, that reply took me completely by surprise. (list) as a
way of saying "I'm going to build a list, starting from
empty" is very nice.

This make me think. Perhaps

(defconstant empty-stack nil)
.
.
.
(let ((stack empty-stack)) ... (push ...))

is clearer. Perhaps

(defun empty-stack () nil)
.
.
.
(let ((stack (empty-stack))) ... (push ...))

paves the way for

(defun empty-stack ()
  (make-array '(0)
              :adjustable t
              :fill-point t))

(let ((stack (empty-stack))) ... (vector-push-extend ...))

if it later seems desirable.

Hmm, I feel quite a tension between straining to be clear
and keeping things simple by just using the idioms. So which
is more idiomatic

(let (stack) ... (push thing stack) ...)

or

(let ((stack '())) ... (push thing stack) ...) 

remains a live question.

Alan Crowe
Edinburgh
Scotland
From: Matthias Buelow
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <5gqo03F2j0fs8U1@mid.dfncis.de>
szergling <···············@gmail.com> wrote:

> If we agree to get rid of the "lone symbol gets bound to nil" thing, we
> can all write this and be happy.
> 
> (let* (x 0
>       y (* 2 3)
>       z nil)

I can't quite put my finger on it but this proposal tears a tiny little
fibre in my sense of design and it isn't because of breaking a
convention...

Not that it would change anything if "we" agreed to it, of course.

You could always make your own let-style macro and try it out.
From: Timofei Shatrov
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <46a853e5.4732134@news.readfreenews.net>
On 26 Jul 2007 04:58:43 GMT, Matthias Buelow <···@incubus.de> tried to confuse
everyone with this message:

>szergling <···············@gmail.com> wrote:
>
>> If we agree to get rid of the "lone symbol gets bound to nil" thing, we
>> can all write this and be happy.
>> 
>> (let* (x 0
>>       y (* 2 3)
>>       z nil)
>
>I can't quite put my finger on it but this proposal tears a tiny little
>fibre in my sense of design and it isn't because of breaking a
>convention...

Well, it's kind of behaves like SETF:

(setf x 0
      y (* 2 3)
      z nil)

-- 
|Don't believe this - you're not worthless              ,gr---------.ru
|It's us against millions and we can't take them all... |  ue     il   |
|But we can take them on!                               |     @ma      |
|                       (A Wilhelm Scream - The Rip)    |______________|
From: Larry Clapp
Subject: Re: LET* where to put end ) and way
Date: 
Message-ID: <slrnfah8r4.46j.larry@theclapp.homelinux.com>
On 2007-07-26, szergling <···············@gmail.com> wrote:
> Sometimes, I wish let had fewer parentheses. Is it really worth it
> being succinct with specifying nil? How often does anyone do that?
> If we agree to get rid of the "lone symbol gets bound to nil" thing,
> we can all write this and be happy.
>
> (let* (x 0
>        y (* 2 3)
>        z nil)
>   (print z)
>   (format  t "~% (~a,~a)" x y))
>
> (This suggestion probably cannot be taken seriously by anyone, and I
> don't think it's (socially) acceptable to write a slightly different
> let for such trivia, so...)

For some comments on this exact idea, see
http://wiki.alu.org/Potting_Soil:_Lists_and_the_Lisp_Point_of_View.
In particular:

> [...]
> But you can bind more than one variable, so you get a list of
> bindings. Given that, they could've defined LET like this: 
> 
>   (LET (var1 val1
>         var2 val2
>         var3 val3)
>     code1-3)
> 
> but then you get into having to keep track of which argument you're
> on (1st, 2nd, 3rd, ...) to know what role it takes. Below, is J a
> variable to be bound or a value to be assigned? 
> 
>   (LET (a b c d e f g h i j k l m n o p)
>     code)
> 
> You don't know, you have to count! That sucks. So add another set of
> sublists: 
> 
>   (LET ((var1 val1)
>         (var2 val2)
>         (var3 val3))
>     code)
> 
> and it becomes much more apparent, even for this: 
> 
>   (LET ((a b) (c d) (e f) (g h) (i j) (k l) (m n) (o p))
>     code)
> 
> J is a value, not a variable!
> [...]

Just my $0.02.

-- Larry