Clojure Print the contents of a vector - clojure

In Clojure, how do you print the contents of a vector? (I imagine to the console, and usually for debugging purposes). If the answer can be generalized to any Seq that would be good.
Edit:
I should add that it should be a simple function that gives output that looks reasonable, so prints an item per line - so can be easily used for debugging purposes. I'm sure there are libraries that can do it, but using a library really does seem like overkill.

I usually use println. There are several other printing functions that you might want to try. See the "IO" section of the Clojure cheatsheet.
This isn't Java. Just print it, and it will look OK.
You can also use clojure.pprint/pprint to pretty-print it. This can be helpful with large, complex data structures.
These methods work for all of the basic Clojure data structures.
Exception: Don't print infinitely long lazy structures such as what (range) returns--for obvious reasons. For that you may need to code something special.

This works for me:
(defn pr-seq
([seq msg]
(letfn [(lineify-seq [items]
(apply str (interpose "\n" items)))]
(println (str "\n--------start--------\n"
msg "\nCOUNT: " (count seq) "\n"
(lineify-seq seq) "\n---------end---------"))))
([seq]
(pr-seq seq nil)))
Example usages:
(pr-seq [1 2 3])
(pr-seq (take 20 blobs) (str "First 20 of " (count blobs) " Blobs")))

If you want to just print out the elements of the sequence/vector you could just map println to your sequence/vector, but make sure you force map to evaluate using dorun:
(dorun (map println [1 2 3 4]))
This can be applied to sequences too:
(dorun (map println '(1 2 3 4)))
Another way you can do this with apply is to curry map with println and apply it to the sequence/vector:
(apply (partial map println) [[1 2 3 4]])
(apply (partial map println) ['(1 2 3 4)])
Another way you can do this is with doseq:
(doseq [e [1 2 3 4]]
(println e))
(doseq [e '(1 2 3 4)]
(println e))

This one at least stops the text going out too far to the right:
(defn pp
([n x]
(binding [pp/*print-right-margin* n]
(-> x clojure.pprint/pprint)))
([x]
(pp 100 x)))
It is possible to do partials of this function to alter the width.

Related

Good way in clojure to map function on multiple items of coll or seqence

I'm currently learning Clojure, and I'm trying to learn how to do things the best way. Today I'm looking at the basic concept of doing things on a sequence, I know the basics of map, filter and reduce. Now I want to try to do a thing to pairs of elements in a sequence, and I found two ways of doing it. The function I apply is println. The output is simply 12 34 56 7
(def xs [1 2 3 4 5 6 7])
(defn work_on_pairs [xs]
(loop [data xs]
(if (empty? data)
data
(do
(println (str (first data) (second data)))
(recur (drop 2 data))))))
(work_on_pairs xs)
I mean, I could do like this
(map println (zipmap (take-nth 2 xs) (take-nth 2 (drop 1 xs))))
;; prints [1 2] [3 4] [5 6], and we loose the last element because zip.
But it is not really nice.. My background is in Python, where I could just say zip(xs[::2], xs[1::2]) But I guess this is not the Clojure way to do it.
So I'm looking for suggestions on how to do this same thing, in the best Clojure way.
I realize I'm so new to Clojure I don't even know what this kind of operation is called.
Thanks for any input
This can be done with partition-all:
(def xs [1 2 3 4 5 6 7])
(->> xs
(partition-all 2) ; Gives ((1 2) (3 4) (5 6) (7))
(map (partial apply str)) ; or use (map #(apply str %))
(apply println))
12 34 56 7
The map line is just to join the pairs so the "()" don't end up in the output.
If you want each pair printed on its own line, change (apply println) to (run! println). Your expected output seems to disagree with your code, so that's unclear.
If you want to dip into transducers, you can do something similar to the threading (->>) form of the accepted answer, but in a single pass over the data.
Assuming
(def xs [1 2 3 4 5 6 7])
has been evaluated already,
(transduce
(comp
(partition-all 2)
(map #(apply str %)))
conj
[]
xs)
should give you the same output if you wrap it in
(apply println ...)
We supply conj (reducing fn) and [] (initial data structure) to specify how the reduce process inside transduce should build up the result.
I wouldn't use a transducer for a list that small, or a process that simple, but it's good to know what's possible!

Clojure lazy interleave or map functionality with sequences of multiple lengths

I want to coalesce multiple sequences into one lazy sequence. The caveat is that it seems that all the mechanisms in core (map, interleave, etc) to accomplish this will not account for those sequences being multiple lengths. I have seen this similar post but it's not exactly what I was looking for. So basically, the goal is a function "super-fn" that has these characteristics:
=>(defn super-fn [& rest]
...)
=>(apply println (super-fn [1 2 3 ] [1 2 3 4 5]))
1 1 2 2 3 3 4 5
=>nil
It seems like it would be useful to be able to coalesce multiple streams of data like this without knowing their lengths. Is my "super-fn" in the core library and I have just missed it or am I missing some hard aspect of doing this?
I agree with bsvingen, though you could use slightly more elegant implementation:
(defn super-fn
[& colls]
(lazy-seq
(when-let [ss (seq (keep seq colls))]
(concat (map first ss)
(apply super-fn (map rest ss))))))
It also correctly handles empty input sequences:
(super-fn [1 2] []) ; => (1 2)
I'm not aware of any such function in the standard library.
It's not hard to write, though:
(defn super-fn
[& seq-seq]
(when seq-seq
(lazy-seq
(concat (filter identity
(map first seq-seq))
(apply super-fn
(seq
(filter identity
(map next seq-seq))))))))

Better way of creating a flat list out of numbers and vectors

I've got a function like this:
(defn magic
[a b c]
(flatten (conj [] a b c)))
So on these inputs I get the following:
(magic 1 2 3) => (1 2 3)
(magic 1 [2 3] 4) => (1 2 3 4)
My question is, is there a better way of doing this?
The problem can be summarised as:
I don't know whether I will get numbers or vectors as input, but I need to return a single flat list
This could be slightly simplified (and generalized) as:
(defn magic [& args]
(flatten (apply list args)))
Or, as pointed out in the comments, it can be simplified even further (since args above is already a seq):
(defn magic [& args]
(flatten args))
Other than that, I don't see much else that can be improved about this. Is there anything in particular that's bothering you about your implementation?
If you can get seqs of seqs then you need to be more careful. And will have to recursively go into the list. There is a clojure native function for this tree-seq see the examples here:
http://clojuredocs.org/clojure_core/clojure.core/tree-seq
You'd want something like this (untested):
(defn nonempty-seq [x]
"returns x as a seq if it's a non-empty seq otherwise nil/false"
(and (coll? x) (seq x)))
(tree-seq nonempty-seq seq expr)

Clojure recursion and a lazy sequence

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.
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)
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.

Difference between doseq and for in Clojure

What's the difference between doseq and for in Clojure? What are some examples of when you would choose to use one over the other?
The difference is that for builds a lazy sequence and returns it while doseq is for executing side-effects and returns nil.
user=> (for [x [1 2 3]] (+ x 5))
(6 7 8)
user=> (doseq [x [1 2 3]] (+ x 5))
nil
user=> (doseq [x [1 2 3]] (println x))
1
2
3
nil
If you want to build a new sequence based on other sequences, use for. If you want to do side-effects (printing, writing to a database, launching a nuclear warhead, etc) based on elements from some sequences, use doseq.
Note also that doseq is eager while for is lazy. The example missing in Rayne's answer is
(for [x [1 2 3]] (println x))
At the REPL, this will generally do what you want, but that's basically a coincidence: the REPL forces the lazy sequence produced by for, causing the printlns to happen. In a non-interactive environment, nothing will ever be printed. You can see this in action by comparing the results of
user> (def lazy (for [x [1 2 3]] (println 'lazy x)))
#'user/lazy
user> (def eager (doseq [x [1 2 3]] (println 'eager x)))
eager 1
eager 2
eager 3
#'user/eager
Because the def form returns the new var created, and not the value which is bound to it, there's nothing for the REPL to print, and lazy will refer to an unrealized lazy-seq: none of its elements have been computed at all. eager will refer to nil, and all of its printing will have been done.