From: Matthew Denson
Subject: variable binding question
Date: 
Message-ID: <Flcv7.8857$F72.2804680840@newssvr16.news.prodigy.com>
Hi,

I was playing with lisp and ran across the following which I can not
explain.

For the defunctions:
(defun drop-ball (x)
  (let ((count 0))
    (dotimes (n x)
      (setq count (+ count (random 2))))
    count))

(defun do-bell ()
  (let ((s 0)
 (stks '(0 0 0 0 0 0 0 0 0 0)))
    (dotimes (n 200)
      (setq s (drop-ball 9))
      (setf (nth s stks) (1+ (nth s stks))))
    stks))

This is a brief snip out of the listener
[1]>
DROP-BALL
[2]>
DO-BELL
[3]> (do-bell)

(0 4 14 30 56 55 27 12 2 0)               ;;; sum is 200
[4]> (do-bell)

(0 6 27 63 117 100 57 24 6 0)          ;;; sum is 400
[5]>
DO-BELL
[6]> (do-bell)

(0 7 14 28 49 53 27 14 7 1)             ;;; back to 200
[7]>

-----------

[3] acted as I expected, but [4] did not start with a fresh "stks" list.
This
continued until I reevaluated the defun as illustrated with [5] and [6].

This happened in all the version of Common Lisp I have (specifically CLISP
LWW Personal).

So I am obviously missing something in my understanding of variable binding.
Why does stks live between calls to (do-bell)?  How do reinitialize it?

Am I hopeless?  Any help/explainations would be gratefully accepted.

All the best,
Matthew

From: Kalle Olavi Niemitalo
Subject: Re: variable binding question
Date: 
Message-ID: <iznofnmy3zt.fsf@stekt34.oulu.fi>
"Matthew Denson" <·······@yahoo.com> writes:

> (defun do-bell ()
>   (let ((s 0)
>  (stks '(0 0 0 0 0 0 0 0 0 0)))
>     (dotimes (n 200)
>       (setq s (drop-ball 9))
>       (setf (nth s stks) (1+ (nth s stks))))
>     stks))

You're modifying the list (0 0 0 0 0 0 0 0 0 0), which is part of
the program.  Don't do that.  You'd better construct a fresh list
each time the function runs.  (list 0 0 0 0 0 0 0 0 0 0) does
that, as does (copy-list '(0 0 0 0 0 0 0 0 0 0)).
From: Matthew Denson
Subject: Re: variable binding question
Date: 
Message-ID: <J6dv7.8862$8L2.2807146543@newssvr16.news.prodigy.com>
Kalle Olavi Niemitalo <···@iki.fi> wrote in message
····················@stekt34.oulu.fi...
> "Matthew Denson" <·······@yahoo.com> writes:
>
> > (defun do-bell ()
> >   (let ((s 0)
> >  (stks '(0 0 0 0 0 0 0 0 0 0)))
> >     (dotimes (n 200)
> >       (setq s (drop-ball 9))
> >       (setf (nth s stks) (1+ (nth s stks))))
> >     stks))
>
> You're modifying the list (0 0 0 0 0 0 0 0 0 0), which is part of
> the program.  Don't do that.  You'd better construct a fresh list
> each time the function runs.  (list 0 0 0 0 0 0 0 0 0 0) does
> that, as does (copy-list '(0 0 0 0 0 0 0 0 0 0)).

Thank you.  It is clear now.  I had planned to eventually dynamically
generate the list based on a passed in variable to set the number of
rows of pins (9) in the simulation but got bogged down in this.
Wouldn't have had this problem if I had started there.

Thanks again,
Matthew
From: Kent M Pitman
Subject: Re: variable binding question
Date: 
Message-ID: <sfw669u796v.fsf@world.std.com>
"Matthew Denson" <·······@yahoo.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> wrote in message
> ····················@stekt34.oulu.fi...
> > "Matthew Denson" <·······@yahoo.com> writes:
> >
> > > (defun do-bell ()
> > >   (let ((s 0)
> > >  (stks '(0 0 0 0 0 0 0 0 0 0)))
> > >     (dotimes (n 200)
> > >       (setq s (drop-ball 9))
> > >       (setf (nth s stks) (1+ (nth s stks))))
> > >     stks))
> >
> > You're modifying the list (0 0 0 0 0 0 0 0 0 0), which is part of
> > the program.  Don't do that.  You'd better construct a fresh list
> > each time the function runs.  (list 0 0 0 0 0 0 0 0 0 0) does
> > that, as does (copy-list '(0 0 0 0 0 0 0 0 0 0)).
> 
> Thank you.  It is clear now.  I had planned to eventually dynamically
> generate the list based on a passed in variable to set the number of
> rows of pins (9) in the simulation but got bogged down in this.
> Wouldn't have had this problem if I had started there.

Your program also would not have been any longer if you'd done it
the right way!  I can see holding off additional complexity if it's
going to make the program longer, but 
 (make-list n :initial-element 0)
and
 '(0 0 0 0 0 0 0 0 0)
are so similar in text size that it's better to just do it right the
first time.  Of course, you have to add (&optional (n 9)) and change
(drop-ball 9) to (drop-ball n).

I'd also spell "stks" as "stacks".  Personally, it looks to me more like
"steaks" for some reason when you abbreviate it.

I'd also write
 (incf (nth s stacks))
not
 (setf (nth s stacks) (1+ (nth s stacks)))
From: Matthew Denson
Subject: Re: variable binding question
Date: 
Message-ID: <9pkrgk$fo8$1@bob.news.rcn.net>
"Kent M Pitman" <······@world.std.com> wrote in message
····················@world.std.com...
> > Thank you.  It is clear now.  I had planned to eventually dynamically
> > generate the list based on a passed in variable to set the number of
> > rows of pins (9) in the simulation but got bogged down in this.
> > Wouldn't have had this problem if I had started there.
>
> Your program also would not have been any longer if you'd done it
> the right way!  I can see holding off additional complexity if it's
> going to make the program longer, but
>  (make-list n :initial-element 0)
> and
>  '(0 0 0 0 0 0 0 0 0)
> are so similar in text size that it's better to just do it right the

It wan't so much the time spent dealing with complexity as
the time spent finding the functionality in a language
reference. Or posting to a ng. ;-)

> first time.  Of course, you have to add (&optional (n 9)) and change
> (drop-ball 9) to (drop-ball n).
>
> I'd also spell "stks" as "stacks".  Personally, it looks to me more like
> "steaks" for some reason when you abbreviate it.
>
> I'd also write
>  (incf (nth s stacks))
> not
>  (setf (nth s stacks) (1+ (nth s stacks)))

Thanks this is all very helpful!

Matthew
From: Frode Vatvedt Fjeld
Subject: Re: variable binding question
Date: 
Message-ID: <2h669ueaal.fsf@dslab7.cs.uit.no>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> (list 0 0 0 0 0 0 0 0 0 0) does that, as does (copy-list '(0 0 0 0 0
> 0 0 0 0 0)).

..and (make-list 10 :initial-element 0).

-- 
Frode Vatvedt Fjeld
From: Kaz Kylheku
Subject: Re: variable binding question
Date: 
Message-ID: <dMjv7.41319$ob.1146531@news1.rdc1.bc.home.com>
In article <·························@newssvr16.news.prodigy.com>,
Matthew Denson wrote:
>(defun do-bell ()
>  (let ((s 0)
> (stks '(0 0 0 0 0 0 0 0 0 0)))
>    (dotimes (n 200)
>      (setq s (drop-ball 9))
>      (setf (nth s stks) (1+ (nth s stks))))

Note that you are destructively manipulating a quoted object, which
is an error.

>[3] acted as I expected, but [4] did not start with a fresh "stks" list.
>This
>So I am obviously missing something in my understanding of variable binding.

No, it's not an issue of variable binding. There is no question
that the symbol stks is lexically bound to the list '(0 0 0 0 ..)

>Why does stks live between calls to (do-bell)?  How do reinitialize it?

Try (let ((stks (copy-list '(0 0 ... 0 0)))) ...)

You probably want to use a *vector* here anyway, since you are doing
destructive assignment to the elements and performing random access.
From: Karsten Poeck
Subject: Re: variable binding question
Date: 
Message-ID: <9pkrk0$dmh$1@news.wanadoo.es>
By using '(0 ...0) you are declaring that stks is a constant.
Later you access with nth, so you are desructively changing the constant.

Try (list 0 ...) to get a fresh list on any call.

Anyhow it seems that a list is not the right datastructure, why don't you
use an array?

Karsten
"Matthew Denson" <·······@yahoo.com> wrote in message
······························@newssvr16.news.prodigy.com...
> Hi,
>
> I was playing with lisp and ran across the following which I can not
> explain.
>
> For the defunctions:
> (defun drop-ball (x)
>   (let ((count 0))
>     (dotimes (n x)
>       (setq count (+ count (random 2))))
>     count))
>
> (defun do-bell ()
>   (let ((s 0)
>  (stks '(0 0 0 0 0 0 0 0 0 0)))
>     (dotimes (n 200)
>       (setq s (drop-ball 9))
>       (setf (nth s stks) (1+ (nth s stks))))
>     stks))
>
> This is a brief snip out of the listener
> [1]>
> DROP-BALL
> [2]>
> DO-BELL
> [3]> (do-bell)
>
> (0 4 14 30 56 55 27 12 2 0)               ;;; sum is 200
> [4]> (do-bell)
>
> (0 6 27 63 117 100 57 24 6 0)          ;;; sum is 400
> [5]>
> DO-BELL
> [6]> (do-bell)
>
> (0 7 14 28 49 53 27 14 7 1)             ;;; back to 200
> [7]>
>
> -----------
>
> [3] acted as I expected, but [4] did not start with a fresh "stks" list.
> This
> continued until I reevaluated the defun as illustrated with [5] and [6].
>
> This happened in all the version of Common Lisp I have (specifically CLISP
> LWW Personal).
>
> So I am obviously missing something in my understanding of variable
binding.
> Why does stks live between calls to (do-bell)?  How do reinitialize it?
>
> Am I hopeless?  Any help/explainations would be gratefully accepted.
>
> All the best,
> Matthew
>
>