map print vs map println in Clojure - clojure

I'm wondering why the following have different output orders in an nREPL
(map println [1 2 3])
Result:
1
2
3
(nil nil nil)
Versus
(map print [1 2 3])
Result:
(nil nil nil)123
Why does applying print show the return value and then display 123?

Also to note, that this works in REPL, in the code you need to use (dorun), as map produces a lazy sequence, and dorun actually forces print to happen:
(dorun (map print [1 2 3])) ;=> 123

Actually, you may see a different order if you run the second one multiple times. print does not print any newlines, so the output buffer is not flushed. You could very well also see:
Result:
123(nil nil nil)
I suppose the first example could possibly change order, too, but the REPL has *flush-on-newline* set to true by default.

It looks pretty much like result of output stream buffering.
You could forcibly print all data in output stream buffer by calling flush function:
(defn print! [& args]
(apply print args)
(flush))
(map print! [1 2 3])
; => 123(nil nil nil)

Related

Printing inside a for loop

I was practicing one Clojure tutorial and had to ensure that a for loop was executed so I put a println command there, but it did not display messages.
So now I have got the question...
This code prints Tom's name:
(ns tutorial.core)
(defn -main []
(println 'Jane)
(for [a ['Tom]]
(println a))
;; 'Kate
)
tutorial.core> (-main)
Jane
Tom
(nil)
tutorial.core>
but this not:
(ns tutorial.core)
(defn -main []
(println 'Jane)
(for [a ['Tom]]
(println a))
'Kate
)
tutorial.core> (-main)
Jane
Kate
tutorial.core>
Why? In which cases can we expect that println will not print texts?
for is not a loop, it is a sequence comprehension which returns a lazy sequence. Your for expression will therefore only execute its side-effects (calls to println) when the returned sequence is evaluated. The REPL evaluates the values returned from your calls to -main so it can print them.
Your first example returns a lazy sequence which is evaluted by the REPL causing the (println 'Tom) call to be evaluated. Since println returns nil, the resulting sequence contains a single nil value - this is the (nil) you see in the output.
Your second example creates the same sequence but does not evaluate it, instead 'Kate is returned from the function and the REPL prints that.
If you want an imperative for loop you should use doseq:
(defn -main []
(println 'Jane)
(doseq [a ['Tom]]
(println a))
'Kate)
As Lee says, if you only want side effects like printing, a doseq is the best solution as it never returns a value other than nil.
If you do want to use a for loop, you can remove the laziness by wrapping it inside a (vec ...) expression, which will force the for loop to run immediately. Thus we get:
(println :start)
(vec
(for [a [1 2 3]]
(println a)))
(println :end)
with result:
:start
1
2
3
:end
Without the vec, we get the behavior you saw:
(println :start)
(for [a [1 2 3]]
(println a))
(println :end)
with result:
:start
:end
I almost never want a lazy result, as the uncertainty over when a computation occurs can make debugging difficult. I use the above construct so often that I wrote a small macro forv that always returns a vector result, similar to the mapv function.

why does clojure's map println only works in repl?

I use lein new app test-println to create a clojure app and launch the repl with lein repl, then I enter (map println [1 2 3 4 5 6]) and get the expected result:
test-println.core=> (map println [1 2 3 4 5 6])
1
2
3
4
5
6
(nil nil nil nil nil nil)
However if I add (map println [1 2 3 4 5 6]) to the end of src/test_println/core.clj:
(ns test-println.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!")
(map println [1 2 3 4 5 6]))
lean run prints only Hello, World!.
map is lazy. To quote the first sentence of the documentation (emphasis added):
Returns a lazy sequence consisting of the result of applying f to the
set of first items of each coll, followed by applying f to the set of
second items in each coll, until any one of the colls is exhausted.
The REPL forces evaluation of the expression to show the result, but nothing in your code does. dorun would solve this, but you probably should look at doseq / doall instead.
If your goal is to run a single procedure over every item in a single collection, you should use run!:
(run! println [1 2 3 4 5 6])
;; 1
;; 2
;; 3
;; 4
;; 5
;; 6
;;=> nil
In cases where the action you need to perform on each collection is more complex than simply applying an existing function, doseq may be more convenient, but run! is a better choice here.

How to print each item of list in separate line clojure?

I'm very new in clojure. I want to print each item of list in newline. I'm trying like this:
user=> (def my-list '(1 2 3 4 5 ))
;; #'user/my-list
user=> my-list
;; (1 2 3 4 5)
user=> (apply println my-list)
;; 1 2 3 4 5
;; nil
But I want my output must be:
1
2
3
4
5
nil
can anyone tell me, How can I do this? Thanks.
If you already have a function that you would like to apply to every item in a single sequence, you can use run! instead of doseq for greater concision:
(run! println [1 2 3 4 5])
;; 1
;; 2
;; 3
;; 4
;; 5
;;=> nil
doseq is useful when the action you want to perform is more complicated than just applying a single function to items in a single sequence, but here run! works just fine.
This kind of use case (perform a side effect once for each member of a sequence) is the purpose of doseq. Using it here would be like
(doseq [item my-list]
(println item))
Note that this will not print nil but will return it. Working with it in the REPL will see the return values of all expressions printed, but doesn't happen in e.g. starting your project as a terminal program.
Another strategy would be to build a string from the list that you want to print and then just print the string.
user> (defn unlines [coll]
(clojure.string/join \newline coll))
#'user/unlines
user> (unlines [1 2 3 4 5])
"1\n2\n3\n4\n5"
user> (println (unlines [1 2 3 4 5]))
1
2
3
4
5
nil

Clojure Print the contents of a vector

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.

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.