Pursuing the thinking behind my original comment, I challenged myself to
see how many ways I could write a function equivalent to list* without
using _spread_ (assuming I had the full Clojure API available to me --
which, of course, the author of list* did not have). Here are four ways:
*(defn second-list*
[& args]
(concat (butlast args) (last args)))
(defn third-list*
[& args]
(let [r-args (reverse args)]
(reduce conj (seq (first r-args)) (rest r-args))))
(defn fourth-list*
[& args]
(let [r-args (reverse args)]
(loop [remaining (rest r-args)
accum (first r-args)]
(if (empty? remaining)
accum
(recur (rest remaining)
(cons (first remaining) accum))))))
(defn fifth-list*
[& args]
(if (empty? (rest args))
(first args)
(cons (first args) (apply fifth-list* (rest args)))))*
But, alas, each of the four is a slowpoke relative to the original:
user> (time (dotimes [_ 100000] (list* 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 26.558 msecs"
user> (time (dotimes [_ 100000] (second-list* 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 97.019 msecs"
user> (time (dotimes [_ 100000] (third-list* 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 96.829 msecs"
user> (time (dotimes [_ 100000] (fourth-list* 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 100.863 msecs"
user> (time (dotimes [_ 100000] (fifth-list* 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 75.925 msecs"
Here is the comparable timing for Ben's list+ alternative:
user> (time (dotimes [_ 100000] (list+ 1 2 3 4 5 6 7 [8 9])))
"Elapsed time: 84.891 msecs"
--Larry
On 10/9/12 5:57 PM, Ben Wolfson wrote:
I took Larry's comment to mean that one could implement list* without
spread ....
--
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