Ricardo Sanchez
Ricardo Sanchez

Reputation: 5157

How to do a for-loop in Clojure?

I'm learning myself some Clojure and I'm using Quil. I would like to know how to translate a for-loop into Clojure:

This is how I would do it in Java or similar languages:

for ( int i = 0; i < numSides; i++ ) {
    float posX = cos( theta * i );
    float posY = sin( theta * i );
    ellipse( posX, posY, polySize, polySize );
}

My Clojure attempt:

  (let [theta (/ PI num-sides)
        angle (range 0 num-sides)
        pos-x (cos (* theta angle))
        pos-y (sin (* theta angle))]
    (dorun (map #(ellipse % % % %) pos-x pos-y poly-size poly-size)))

Upvotes: 4

Views: 2059

Answers (4)

Dave Liepmann
Dave Liepmann

Reputation: 1369

Doseq with range is often appropriate for looping over a specific number of values in order to create side effects. I would implement your loop as follows:

(doseq [i (range 0 num-sides)]
  (ellipse (cos (* theta i)) 
           (sin (* theta i)) 
           poly-size 
           poly-size))

Upvotes: 1

mudphone
mudphone

Reputation: 946

Perhaps this is somewhat academic, but I like using Clojure's "for comprehensions" for this kind of thing. The code would look like this:

(dorun
  (for [i (range num-sides)
        :let [pos-x (Math/cos (* i theta))
              pos-y (Math/sin (* i theta))]]
    (quil.core/ellipse pos-x pos-y poly-size poly-size)))

Upvotes: 2

mikera
mikera

Reputation: 106351

If you genuinely want an C-style for loop, then my clojure-utils libray has a handy for-loop macro that lets you do stuff like:

(for-loop [i 0 , (< i num-sides) , (inc i)]
  ... do stuff.....)

Normally however, I will find myself using one of the following:

  • (dotimes [i num-sides] ....) - do something a specific number of times
  • (doseq [x some-sequence] ....) - do something for every element in a sequence
  • (for [i (range n)] ...) - constructing a list with n elements

Upvotes: 4

Ankur
Ankur

Reputation: 33637

All the ways that you have looked for are basically to work with sequences where as a loop is about executing things for a specific number of times. Clojure provide dotimes to do things for certain number of times:

(dotimes [i 10]
  (println i))

So your code becomes something like:

 (dotimes [i num-sides]
   (let [pos-x (cos (* theta i))
         pos-y (sin (* theta i))]
         (ellipse pos-x pos-y poly-size poly-size)))

Upvotes: 7

Related Questions