4

Ok, I'm a bit stuck on this one, can I actually do what I'm trying to do with this part of the code below:

(recur (conj (get-links (first links)) (rest links))))

get-links returns a sequence of urls which is fed into the initial process-links call then should recurse.

The first link i feed in works, but then the second link where I'm trying to conj one sequence on to another gives me the following error.

"Clojure.lang.LazySeq@xxxxxxx"

Now I'm wondering, is this conj'ing the reference to the instruction to generate the "rest" (rest links) of the un-evaluated sequence?

(defn process-links
  [links]
  (if (not (empty? links))
    (do
      (if (not (is-working (first links)))
        (do
          (println (str (first links) " is not working"))
          (recur (rest links)))
        (do
          (println (str (first links) " is working"))
          (recur (conj (get-links (first links)) (rest links))))))))

If I'm totally wrong in my approach to this, let me know.

2
  • 3
    Some tips on you code. You should not write (not (empty? ...)) because the implmentation of empty? is (not (seq ...)). So your basiclly writing (not (not (seq ...))). Just writting (seq ...) is the common pattern and I dont think you have to do (println (str ....)) you can just do (println ...) in most cases. Instead of (if (not ...)) use (if-not ). The topmost if does not have a 'else'-part use the when function in cases like that. The first 'do' function can be thrown away too (spezially when using 'when', the 'when' makro always adds a 'do'. I hope that helps. Commented Dec 14, 2011 at 23:42
  • Thanks for the tips, makes sense looking at it :) Commented Dec 15, 2011 at 20:51

2 Answers 2

7

conj adds an item to a collection. Using it on two collections creates a nested structure. You probably want to concat the two sequences instead.

To illustrate:

user> (conj [1 2 3] [4 5 6])
[1 2 3 [4 5 6]]
user> (concat [1 2 3] [4 5 6])
(1 2 3 4 5 6)
Sign up to request clarification or add additional context in comments.

1 Comment

Yup that did it! Another function I didn't know about! Had to switch my (get-links (first links)) and (rest links) but that seems to have done the trick. Thanks!
1

Regarding the "Clojure.lang.LazySeq@xxxxxxx" thing:

The problem is in this snippet:

(println (str (first links) " is working"))

Here you use the string concatenation function str to glue together (first links), which is not a string in this case, and " is working", which is a string. What does str do with a non-string argument? It calls the .toString method on it. What does .toString do for Clojure data? Not always the thing you'd want.

The solution is to use the pr family of functions. pr writes Clojure data to a stream in a way that is recognized by the clojure reader. Two examples of how the above snipped can be rewritten:

(do (pr (first links))
    (println " is working"))

;; Sligtly less efficient since a string must be created
(println (pr-str (first links)) "is working")

Note that if you give multiple arguments to println it will print all items with spaces in between.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.