Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my string function return a clojure.lang.LazySeq@xxxxxx?

Tags:

clojure

I've defined the following 3 functions using the leiningen REPL:

(defn rand-int-range [floor ceiling] (+ floor (rand-int (- ceiling floor))))

(defn mutate-index
  "mutates one index in an array of char and returns the new mutated array"
  [source idx]
  (map
    #(if (= %1 idx)
       (char (+ (int %2) (rand-int-range -3 3)))
       %2)
    (iterate inc 0)
    source))

(defn mutate-string
  [source]
  (str
    (mutate-index
      (.toCharArray source)
      (rand-int (alength (.toCharArray source))))))

When I run (mutate-string "hello"), instead of the REPL printing out the mutated string, it is printing out clojure.lang.LazySeq@xxxxxx where the 'xxxxx' is a random sequence of numbers and letters. I would expect it to instead print something like "hellm" Is this really giving me a string back like I think? If it is, how can I get the REPL to show me that string?

like image 831
user1020853 Avatar asked Oct 30 '11 16:10

user1020853


2 Answers

1) To convert a sequence of characters (which is what mutate-index returns) to a string, use apply str rather than just str. The latter operates on objects, not sequences.

(str [\a \b \c])
=> "[\\a \\b \\c]"

(apply str [\a \b \c])
=> "abc"

2) Strings are seqable, meaning you can use sequence functions like map and filter on them directly without stuff like .toCharArray.

3) Consider using map-indexed or StringBuilder to accomplish what you're trying to do:

(apply str (map-indexed (fn [i c] (if (= 3 i) \X c)) "foobar"))
=> "fooXar"

(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X)))
=> "fooXar"
like image 184
Justin Kramer Avatar answered Nov 22 '22 06:11

Justin Kramer


That happens, because the map function returns a lazy sequence, which string reprsentation is just the class name and a hash (clojure.lang.LazySeq@xxxxxx).

In order to get the original working you need to first to get the lazy sequence evaluated. By using the (apply str ...) like Justin adviced that should happen and you should get the correct result.

Otherwise normally if you see similar problems due to not evaluating a lazy sequence you should try out function doall, which forces the evalutation of a lazy sequence

like image 43
Verneri Åberg Avatar answered Nov 22 '22 06:11

Verneri Åberg