From: Anand Hariharan
Subject: Re: Computationally arrive at index of list-ref
Date: 
Message-ID: <1187201469.030109.323040@g4g2000hsf.googlegroups.com>
Caveat emptor:  Newbie in Lisp/Scheme (altogether spent ! > 3 hours).
Pretty much my first stab at anything functional.  Of course, this is
my first post in these parts.

Context:  Am using a Scheme extension for the ACIS modeller (I am told
it is a dialect of Elk with some extensions).  "part", "entity" etc.,
are names defined in this extension.  Am trying to assign a different
colour to each ACIS body that I load into this shell.

<If any of the above paragraph makes my post OT, please replace
"(part:entities)" with "MyList", and "entity:set-color" as "MyFunc" in
the code snippet below.  Thank you for understanding.>


I tried something like so:


(define Num (ceiling (expt (length (part:entities)) (/ 1 3))))
(do ((r 0 (+ r 1))) ((>= r Num) 'stop)
  (do ((g 0 (+ g 1))) ((>= g Num) 'stop)
    (do ((b 0 (+ b 1))) ((>= b Num) 'stop)
      (define Idx (+ b (+ (* g Num) (* r Num Num))))
      (cond (= Idx Num) 'stop)
      (entity:set-color (list-ref (part:entities) Idx)
                        (color:rgb (/ (+ 1 r) Num)
                                   (/ (+ 1 g) Num)
                                   (/ (+ 1 b) Num)
                        )
      )
    )
  )
)


1. Feel free to critique the code and/or the style, offer suggestions.
   Would appreciate if you keep it constructive.  If there is a better
   way to go about it, I would definitely like to hear it.

2. The specific problem that I have run into is that this interpreter
   does not like the fact that 'Idx' was computationally arrived at.
   I have tried to "round off" Idx, naively believing that it would
   convert it from real to integer, but list-ref seems to insist that
   it is not an integer.

3. Is my 'stop within the cond statement, really like "break;" in a
   procedural language?


thank you for listening,
- Anand

From: Anand Hariharan
Subject: Re: Computationally arrive at index of list-ref
Date: 
Message-ID: <1187212405.288686.211450@19g2000hsx.googlegroups.com>
On Aug 15, 1:28 pm, Jens Axel S�gaard <······@soegaard.net> wrote:
> > I tried something like so:
>
> > (define Num (ceiling (expt (length (part:entities)) (/ 1 3))))
> > (do ((r 0 (+ r 1))) ((>= r Num) 'stop)
> >   (do ((g 0 (+ g 1))) ((>= g Num) 'stop)
> >     (do ((b 0 (+ b 1))) ((>= b Num) 'stop)
> >       (define Idx (+ b (+ (* g Num) (* r Num Num))))
> >       (cond (= Idx Num) 'stop)
> >       (entity:set-color (list-ref (part:entities) Idx)
> >                         (color:rgb (/ (+ 1 r) Num)
> >                                    (/ (+ 1 g) Num)
> >                                    (/ (+ 1 b) Num)
> >                         )
> >       )
> >     )
> >   )
> > )
>
> > 1. Feel free to critique the code and/or the style, offer suggestions.
> >    Would appreciate if you keep it constructive.  If there is a better
> >    way to go about it, I would definitely like to hear it.
>
> > 2. The specific problem that I have run into is that this interpreter
> >    does not like the fact that 'Idx' was computationally arrived at.
> >    I have tried to "round off" Idx, naively believing that it would
> >    convert it from real to integer, but list-ref seems to insist that
> >    it is not an integer.
>
> > 3. Is my 'stop within the cond statement, really like "break;" in a
> >    procedural language?
>
> No.
>
> And the placement of define seems fishy to me.
>

Thank you for responding, Jens.


> Is the following displaying what you expect to see?
>

Am afraid not.  I get the same error as I described in #2 above viz.,

"*** Error list-ref: wrong argument type real (expected integer)".


> (define Num (ceiling (expt (length (part:entities)) (/ 1 3))))
> (do ((r 0 (+ r 1))) ((>= r Num) 'stop)
>    (display r) (newline)
>    (do ((g 0 (+ g 1))) ((>= g Num) 'stop)
>      (display "  ") (display g) (newline)
>      (do ((b 0 (+ b 1))) ((>= b Num) 'stop)
>        (display "    ") (display b) (newline)
>        (define Idx (+ b (+ (* g Num) (* r Num Num))))
>        (cond (= Idx Num) 'stop)
>        (entity:set-color (list-ref (part:entities) Idx)
>                          (color:rgb (/ (+ 1 r) Num)
>                                     (/ (+ 1 g) Num)
>                                     (/ (+ 1 b) Num)
>                          )
>        )
>      )
>    )
> )
>

Let me explain what I am trying to do:

I would like to iterate through the elements in a list.  For each
element in the list, I want to call a function with three double
values.  Each of these double values can range from 0 through 1.  The
combination of the three values should be unique for each element in
the list.

To do so, the "scheme" I came up with, is as follows:

* Find the cube root of the number of elements in the list, and round
it up to the next highest number.  Call this Num.
* Have a triple nested for-loop within which, increment the indices
from 0 through N-1 (both inclusive).
* Access each element in the list using list-ref.
* Pass three double values based on each of the index value divided by
'Num'.

thank you for all help,
- Anand
From: Pascal Bourguignon
Subject: Re: Computationally arrive at index of list-ref
Date: 
Message-ID: <877inw4gmk.fsf@thalassa.informatimago.com>
Anand Hariharan <······················@gmail.com> writes:

> Let me explain what I am trying to do:
>
> I would like to iterate through the elements in a list.  For each
> element in the list, I want to call a function with three double
> values.  Each of these double values can range from 0 through 1.  The
> combination of the three values should be unique for each element in
> the list.
>
> To do so, the "scheme" I came up with, is as follows:
>
> * Find the cube root of the number of elements in the list, and round
> it up to the next highest number.  Call this Num.
> * Have a triple nested for-loop within which, increment the indices
> from 0 through N-1 (both inclusive).
> * Access each element in the list using list-ref.

Why? 

> * Pass three double values based on each of the index value divided by
> 'Num'.


You start with: "I would like to iterate through the elements in a
list."  and you end with three loops that have nothing to do with
iterating through elements in a list.  Why?

(loop
   :with max = (ceiling (expt (length (part:entities)) 1/3))
   :with r = 0 :and g = 0 :and b = 0
   :for entity :in (part:entities)
   :do (entity:set-color entity
                         (color:rgb (coerce (/ r max) 'double-float)
                                    (coerce (/ g max) 'double-float)
                                    (coerce (/ b max) 'double-float)))
       (incf b)
       (when (= b max)
          (setf b 0)
          (incf g)
          (when (= g max)
             (setf g 0)
             (incf r))))


Otherwise, you can also do it with three embedded loops, if that's
important for you:

(let ((max     (ceiling (expt (length (part:entities)) 1/3)))
      (current (part:entities)))
  (loop
     :named main-loop
     :for r :from 0 :below max
     :do (loop
            :for g :from 0 :below max
            :do (loop
                   :for b :from 0 :below max
                   :do (entity:set-color
                        (pop current)
                        (color:rgb (coerce (/ r max) 'double-float)
                                   (coerce (/ g max) 'double-float)
                                   (coerce (/ b max) 'double-float)))
                        (when (endp current)
                          (return-from 'main-loop))))))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Anand Hariharan
Subject: Re: Computationally arrive at index of list-ref
Date: 
Message-ID: <1187289808.949539.95040@50g2000hsm.googlegroups.com>
On Aug 15, 4:44 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> Anand Hariharan <······················@gmail.com> writes:
> > Let me explain what I am trying to do:
>
> > I would like to iterate through the elements in a list.  For each
> > element in the list, I want to call a function with three double
> > values.  Each of these double values can range from 0 through 1.  The
> > combination of the three values should be unique for each element in
> > the list.
>
> > To do so, the "scheme" I came up with, is as follows:
>
> > * Find the cube root of the number of elements in the list, and round
> > it up to the next highest number.  Call this Num.
> > * Have a triple nested for-loop within which, increment the indices
> > from 0 through N-1 (both inclusive).
> > * Access each element in the list using list-ref.
>
> Why?
>
> > * Pass three double values based on each of the index value divided by
> > 'Num'.
>
> You start with: "I would like to iterate through the elements in a
> list."  and you end with three loops that have nothing to do with
> iterating through elements in a list.  Why?
>

Thank you for responding, Pascal.

I tried to write my program based on whatever I could scratch up from
reading the documentation.  Your code below suggests that one could
write Lisp/Scheme almost as though one was writing in a Procedural
language.  Clearly, this is something very new to me.

> (loop
>    :with max = (ceiling (expt (length (part:entities)) 1/3))
>    :with r = 0 :and g = 0 :and b = 0
>    :for entity :in (part:entities)
>    :do (entity:set-color entity
>                          (color:rgb (coerce (/ r max) 'double-float)
>                                     (coerce (/ g max) 'double-float)
>                                     (coerce (/ b max) 'double-float)))
>        (incf b)
>        (when (= b max)
>           (setf b 0)
>           (incf g)
>           (when (= g max)
>              (setf g 0)
>              (incf r))))
>
> Otherwise, you can also do it with three embedded loops, if that's
> important for you:
>
> (let ((max     (ceiling (expt (length (part:entities)) 1/3)))
>       (current (part:entities)))
>   (loop
>      :named main-loop
>      :for r :from 0 :below max
>      :do (loop
>             :for g :from 0 :below max
>             :do (loop
>                    :for b :from 0 :below max
>                    :do (entity:set-color
>                         (pop current)
>                         (color:rgb (coerce (/ r max) 'double-float)
>                                    (coerce (/ g max) 'double-float)
>                                    (coerce (/ b max) 'double-float)))
>                         (when (endp current)
>                           (return-from 'main-loop))))))
>

Unfortunately, the Elk dialect rejects both code snippets (it is
unaware of the "loop" or ":for" constructs).

thank you once again,
- Anand
From: Pascal Bourguignon
Subject: Re: Computationally arrive at index of list-ref
Date: 
Message-ID: <87sl6j1d0g.fsf@thalassa.informatimago.com>
Anand Hariharan <······················@gmail.com> writes:
> I tried to write my program based on whatever I could scratch up from
> reading the documentation.  Your code below suggests that one could
> write Lisp/Scheme almost as though one was writing in a Procedural
> language.  Clearly, this is something very new to me.
>
>> (loop
>>    :with max = (ceiling (expt (length (part:entities)) 1/3))
>>    :with r = 0 :and g = 0 :and b = 0
>>    :for entity :in (part:entities)
>>    :do (entity:set-color entity
>>                          (color:rgb (coerce (/ r max) 'double-float)
>>                                     (coerce (/ g max) 'double-float)
>>                                     (coerce (/ b max) 'double-float)))
>>        (incf b)
>>        (when (= b max)
>>           (setf b 0)
>>           (incf g)
>>           (when (= g max)
>>              (setf g 0)
>>              (incf r))))
>> [...]
>
> Unfortunately, the Elk dialect rejects both code snippets (it is
> unaware of the "loop" or ":for" constructs).

Yes, I answered on comp.lang.lisp which is more Common Lisp oriented
than scheme.

But you can do similarly in scheme with named lets:

(let loop ((max (ceiling (expt (length (part:entities)) (/ 1 3))))
           (r 0)
           (g 0)
           (b 0)
           (current (part:entities)))
   (entity:set-color 
       (car current)
       (color:rgb (/ r max)
                  (/ g max)
                  (/ b max)))
   (set! b (+ 1 b))
   (cond ((= b max) 
          (set! b 0)
          (set! g (+ 1 g))
          (cond ((= g max)
                 (set! g 0)
                 (set! r (+ 1 r))))))
   (if (not (null? (cdr current)))
      (loop max r g b (cdr current))))

         
And I'd bet there's half an implementation of the Common Lisp LOOP
macro in scheme somewhere...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Joel J. Adamson
Subject: I'm turning into one heck of a lisper (was: Computationally arrive at index of list-ref)
Date: 
Message-ID: <87lkcbcfwo.fsf_-_@W0053328.mgh.harvard.edu>
Pascal Bourguignon <···@informatimago.com> writes:

> Anand Hariharan <······················@gmail.com> writes:
>
> But you can do similarly in scheme with named lets:
>
> (let loop ((max (ceiling (expt (length (part:entities)) (/ 1 3))))
>            (r 0)
[snip]         
> And I'd bet there's half an implementation of the Common Lisp LOOP
> macro in scheme somewhere...

Pascal, reading your code (and much more of any kind of Lisp) makes a
lot more sense now:

Last night I'm sittin' there thinking "How do I multiply each element
of this list by 2...I know there's a procedure called map..." and
tried it a bunch of times just using

(map * 2 '(insert your favorite list here))

Which of course makes no sense, but then I realized the second
argument must be a procedure: so I *wrote a procedure* and stuck it in
there.

(map (lambda (x) (* 2 x)) '(8 6 7 5 3 0 9))

A-ha!  I finally realized that lambda is really a SYMBOL!  A symbolic
representation of a procedure -- yet again lexical scoping only makes
sense here since the symbols must have meaning *as symbols*.  This is
about my twelfth light-bulb moment in studying Scheme, I'm well on my
way to completing my "afternoon of study."

[now, is there a simpler way to do the multiplication above?  This
makes so much sense to my mathematical mind that it feels really
friggin' simple already, even though it would have looked complicated
to me 24 hours ago]

Joel

-- 
Joel J. Adamson
Biostatistician
Pediatric Psychopharmacology Research Unit
Massachusetts General Hospital
Boston, MA  02114
(617) 643-1432
(303) 880-3109

"It can be interesting to study ancient philosophy, but more as a kind
of accident report than to teach you anything useful."
                                        --Paul Graham
					http://www.paulgraham.com/raq.html