Hello, I'm new to clojure and have a question concerning recur and
lazy seqs.

I implemented a function to calculate the perimeter of a polygon. As
I'm used to Java and imperative programming, my first approach was to
use loop/recur ('euclidean-distance' is a helper-function that
calculates the distance between two points):

(defn polygon-perimeter
  "Calculates the perimeter of a polygon. For this purpose it adds
  up the distances between all points."
  [& pn]
    (loop [p 0.0, points (conj (vec pn) (first pn))]
      (if (> (count points) 1)
        (recur (+ p (euclidean-distance (first points) (second
points)))
                 (rest points))
        p)))

I found that this doesn't look very functional, so I tried a different
approach with use of the sequence library;

(defn better-perimeter
  "Calculates the perimeter of a polygon. For this purpose it adds
  up the distances between all points."
  [& pn]
  (reduce +
    (map #(euclidean-distance (first %) (second %))
            (partition 2 1 (conj (vec pn) (first pn))))))

This looks very nice. But then I compared the performance of both
implementations:

(dotimes [_ 5] (time (polygon-perimeter [0 1] [1 0] [3 2] [2 3] [0
2])))
"Elapsed time: 1.129296 msecs"
"Elapsed time: 0.156261 msecs"
"Elapsed time: 0.153229 msecs"
"Elapsed time: 0.153613 msecs"
"Elapsed time: 0.152975 msecs"

(dotimes [_ 5] (time (better-perimeter [0 1] [1 0] [3 2] [2 3] [0
2])))
"Elapsed time: 2.809387 msecs"
"Elapsed time: 0.221396 msecs"
"Elapsed time: 0.214933 msecs"
"Elapsed time: 0.214048 msecs"
"Elapsed time: 0.217317 msecs"

As you can see, the loop/recur version is a bit faster (not
significantly but a little bit). This leads me to a general question:

What would be the better implementation? When should I use loop/recur
and when seq library functions? Stuart Halloway writes in his book
"Use recur when you are producing scalar values or small, fixed
sequences" and also "Know the sequences library. You can often write
code without using recur or the lazy apis at all." Pehaps you have
some more rules of the thumb?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to