I actually quite like the with-out-str
approach to this sort of thing:
(with-out-str
(println)
(doseq [s ["one" "two"]]
(println (.toUpperCase ^String s))))
It seems to be about 2-3x slower than your original approach and Martin's "combined map and interpose" variant with type hints added (and ~30x faster than cl-format
, which however clearly wins on the coolness factor :-)). (See end of this answer for a note on hinting & reflection.)
Another version just to keep up the timtowtdi spirit: for the ultimate in speed (up to ~2x speedup over your original version), should you have reason to care about that, you could use
(loop [sb (doto (StringBuilder.)
(.append \newline))
strs ["one" "two"]]
(if-let [s (first strs)]
(do (.append sb (.toUpperCase ^String s))
(.append sb \newline)
(recur sb (next strs)))
(.toString sb)))))
Somewhat tangentially to the main question, I timed all approaches after getting rid of all reflection warnings; in particular, I used
(def up #(.toUpperCase ^String %))
(Incidentally, #(.foo %)
seems to be used much more often than memfn
even when no type hints are specified.)