From: landspeedrecord
Subject: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <1193268131.553063.205760@z24g2000prh.googlegroups.com>
Here is a bit of code...

(defun example ()
  (let ((listlen (1- (length *text-array*))))
    (loop for i from listlen downto 0
	  for j = (nth i *text-array*)
                   ;position of first alpha character.
          do (let*      .....insert bindings plus body of let* code
here etc...

So... Why does that last "let*" work while a "let" in the same place
does not and throws an error about how the variables in the bindings
following the let have no value?

The following is the bit of code I was working on that brought up the
issue... it is part of code that I am posting in a seperate thread at
the same time as this one...  If you want to see the documentation for
it to make sense of it see the thread called ""Read stuff from a file
and chop it up to do stuff" code advice wanted."

(defun string-list-nonchar-fixer ()
  (let ((newlist nil)
        (listlen (1- (length *text-array*))))
    (loop for i from listlen downto 0
	  for j = (nth i *text-array*)
                   ;position of first alpha character.
          do (let* ((firstcut (first-alphachar-pos j))
                   ;position of first ending-group non-alpha
character.
                   (lastcut (1+ (last-alphachar-pos j)))
                   ;total length of the string minus 1.
                   (stringlen (length j))
                   ;only alphabetic characters in string?
                   (all-alpha (if (and (= firstcut 0) (= lastcut
stringlen))
                                        T NIL)))
                   ;This cond form pushes all the bits onto "newlist".
                         ;1 - only alphabetic characters in string.
                   (cond (all-alpha (push j newlist))
                         ;2 - non-alphabetic string - pass it along...
                         ((> firstcut lastcut) (push j newlist))
                         ;3 - junk before but not after.
                         ((= lastcut stringlen)
                            (progn (push (subseq j firstcut stringlen)
newlist)
                                   (push (subseq j 0 firstcut)
newlist)))
                         ;4 - junk after but not before.
                         ((= firstcut 0)
                            (progn (push (subseq j lastcut stringlen)
newlist)
                                   (push (subseq j 0 lastcut)
newlist)))
                         ;5 - junk at start and end.
                         (T (progn (push (subseq j lastcut stringlen)
newlist)
                                   (push (subseq j firstcut lastcut)
newlist)
                                   (push (subseq j 0 firstcut)
newlist))))))
         newlist))

From: Carl Taylor
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <UEQTi.269786$ax1.214289@bgtnsc05-news.ops.worldnet.att.net>
landspeedrecord wrote:
> Here is a bit of code...
> 
> (defun example ()
>  (let ((listlen (1- (length *text-array*))))
>    (loop for i from listlen downto 0
>   for j = (nth i *text-array*)
>                   ;position of first alpha character.
>          do (let*      .....insert bindings plus body of let* code
> here etc...
> 
> So... Why does that last "let*" work while a "let" in the same place
> does not and throws an error about how the variables in the bindings
> following the let have no value?

Because the first binding in the let*, <firstcut>,
is referenced by the fourth binding, <all-alpha>.

The fact that it's a "do" clause in <loop> has nothing to
do with it.

Carl Taylor
From: landspeedrecord
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <1193340034.069395.254420@o80g2000hse.googlegroups.com>
CRAP.  I shoulda caught that.  I guess I got confused because my
function was so large + I am still shaky on how to use loop properly.

Thanks.  I thought I was bringing up something esoteric.  Duh.


> The fact that it's a "do" clause in <loop> has nothing to
> do with it.
>
> Carl Taylor
From: Rainer Joswig
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <joswig-D4AD74.01485825102007@news-europe.giganews.com>
In article <························@z24g2000prh.googlegroups.com>,
 landspeedrecord <···············@gmail.com> wrote:

...

> So... Why does that last "let*" work while a "let" in the same place
> does not and throws an error about how the variables in the bindings
> following the let have no value?
> 

This has nothing to do with LOOP. It is a general LET vs. LET* issue.

...

>           do (let* ((firstcut (first-alphachar-pos j))
>                    ;position of first ending-group non-alpha
> character.
>                    (lastcut (1+ (last-alphachar-pos j)))
>                    ;total length of the string minus 1.
>                    (stringlen (length j))
>                    ;only alphabetic characters in string?
>                    (all-alpha (if (and (= firstcut 0) (= lastcut
> stringlen))

You use FIRSTCUT, LASTCUT and STRINGLEN. Both are introduced in the same
LET*. See the documentation of LET and LET*
for the differences in binding the variables.

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


? (LET ((foo 1)
      (bar (+ foo 1)))
  bar)
;Compiler warnings :
;   Undeclared free variable FOO, in an anonymous lambda form.
;   Unused lexical variable FOO, in an anonymous lambda form.
> Error in process listener(1): Unbound variable: FOO
> While executing: #<Anonymous Function #x83ACD66>
> Type :GO to continue, :POP to abort.
> If continued: Retry getting the value of FOO.
Type :? for other options.
1 > 

? (LET* ((foo 1)
       (bar (+ foo 1)))
  bar)
2





>                                         T NIL)))
>                    ;This cond form pushes all the bits onto "newlist".
>                          ;1 - only alphabetic characters in string.
>                    (cond (all-alpha (push j newlist))
>                          ;2 - non-alphabetic string - pass it along...
>                          ((> firstcut lastcut) (push j newlist))
>                          ;3 - junk before but not after.
>                          ((= lastcut stringlen)
>                             (progn (push (subseq j firstcut stringlen)
> newlist)
>                                    (push (subseq j 0 firstcut)
> newlist)))
>                          ;4 - junk after but not before.
>                          ((= firstcut 0)
>                             (progn (push (subseq j lastcut stringlen)
> newlist)
>                                    (push (subseq j 0 lastcut)
> newlist)))
>                          ;5 - junk at start and end.
>                          (T (progn (push (subseq j lastcut stringlen)
> newlist)
>                                    (push (subseq j firstcut lastcut)
> newlist)
>                                    (push (subseq j 0 firstcut)
> newlist))))))
>          newlist))
From: Evan Monroig
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <87myu82gzg.fsf@obakechan.net>
landspeedrecord <···············@gmail.com> writes:

> Here is a bit of code...
>
> (defun example ()
>   (let ((listlen (1- (length *text-array*))))
>     (loop for i from listlen downto 0
> 	  for j = (nth i *text-array*)
>                    ;position of first alpha character.
>           do (let*      .....insert bindings plus body of let* code
> here etc...
>
> So... Why does that last "let*" work while a "let" in the same place
> does not and throws an error about how the variables in the bindings
> following the let have no value?

Try this:

(let ((a 1)
      (b a))
  b)

(let* ((a 1)
       (b a))
  b)

In the first one the bindings are done in parallel (so you cannot access
the binding of A in the binding of B), in the second one in series (so
you can access the binding of A when doing the binding of B).

Evan
From: namekuseijin
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <1193282308.995280.36080@y27g2000pre.googlegroups.com>
On Oct 24, 10:08 pm, Evan Monroig <········@obakechan.net> wrote:
> Try this:
>
> (let ((a 1)
>       (b a))
>   b)
>
> (let* ((a 1)
>        (b a))
>   b)
>
> In the first one the bindings are done in parallel (so you cannot access
> the binding of A in the binding of B), in the second one in series (so
> you can access the binding of A when doing the binding of B).

indeed.  let* is actually a recursive let:

(let* ((a1 v1)(b1 v2)) ...) => (let ((a1 v1)) (let ((b2 v2)) ...))

kinda like cond being a recursive if...
From: namekuseijin
Subject: Re: Why "Let*" and not "Let" after "do" in a loop??? Grrr.
Date: 
Message-ID: <1193289409.250299.72870@q5g2000prf.googlegroups.com>
On Oct 25, 1:18 am, namekuseijin <············@gmail.com> wrote:
> indeed.  let* is actually a recursive let:
>
> (let* ((a1 v1)(b1 v2)) ...) => (let ((a1 v1)) (let ((b2 v2)) ...))

of course, by b1 and b2 I actually meant a2.  sorry...