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))
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
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
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
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...