Clojure loop collection - clojure

I want to know if this is the right way to loop through an collection:
(def citrus-list ["lemon" "orange" "grapefruit"])
(defn display-citrus [citruses]
(loop [[citrus & citruses] citruses]
(println citrus)
(if citrus (recur citruses))
))
(display-citrus citrus-list)
I have three questions:
the final print displays nil, is it ok or how can avoid it?
I understand what & is doing in this example but I donĀ“t see it in other cases, maybe you could provide a few examples
Any other example to get the same result?
Thanks,
R.

First of all your implementation is wrong. It would fail if your list contains nil:
user> (display-citrus [nil "asd" "fgh"])
;;=> nil
nil
And print unneeded nil if the list is empty:
user> (display-citrus [])
;;=> nil
nil
you can fix it this way:
(defn display-citrus [citruses]
(when (seq citruses)
(loop [[citrus & citruses] citruses]
(println citrus)
(if (seq citruses) (recur citruses)))))
1) it is totally ok: for non-empty collection the last call inside function is println, which returns nil, and for empty collection you don't call anything, meaning nil would be returned (clojure function always returns a value). To avoid nil in your case you should explicitly return some value (like this for example):
(defn display-citrus [citruses]
(when (seq citruses)
(loop [[citrus & citruses] citruses]
(println citrus)
(if (seq citruses) (recur citruses))))
citruses)
user> (display-citrus citrus-list)
;;=> lemon
;;=> orange
;;=> grapefruit
["lemon" "orange" "grapefruit"]
2) some articles about destructuring should help you
3) yes, there are some ways to do this. The simplest would be:
(run! println citrus-list)

Answering your last question, you should avoid using loop in Clojure. This form is rather for experienced users that really know what they do. In your case, you may use such more user-friendly forms as doseq. For example:
(doseq [item collection]
(println item))
You may also use map but keep in mind that it returns a new list (of nils if your case) that not sometimes desirable. Say, you are interested only in printing but not in the result.
In addition, map is lazy and won't be evaluated until it has been printed or evaluated with doall.

For most purpose, you can use either map, for or loop.
=> (map count citrus-list)
(5 6 10)
=> (for [c citrus-list] (count c))
(5 6 10)
=> (loop [[c & citrus] citrus-list
counts []]
(if-not c counts
(recur citrus (conj counts (count c)))))
[5 6 10]
I tend to use map as much of possible. The syntax is more concise, and it clearly separates the control flow (sequential loop) from the transformation logic (count the values).
For instance, you can run the same operation (count) in parallel by simply replacing map by pmap
=> (pmap count citrus-list)
[5 6 10]
In Clojure, most operations on collection are lazy. They will not take effect as long as your program doesn't need the new values. To apply the effect immediately, you can enclose your loop operation inside doall
=> (doall (map count citrus-list))
(5 6 10)
You can also use doseq if you don't care about return values. For instance, you can use doseq with println since the function will always return nil
=> (doseq [c citrus-list] (println c))
lemon
orange
grapefruit

Related

Clojure: How to determine if a nested list contains non-numeric items?

I need to write a Clojure function which takes an unevaluated arbitrarily deep nesting of lists as input, and then determines if any item in the list (not in function position) is non-numeric. This is my first time writing anything in Clojure so I am a bit confused. Here is my first attempt at making the function:
(defn list-eval
[x]
(for [lst x]
(for [item lst]
(if(integer? item)
(println "")
(println "This list contains a non-numeric value")))))
I tried to use a nested for-loop to iterate through each item in every nested list. Trying to test the function like so:
=> (list-eval (1(2 3("a" 5(3)))))
results in this exception:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn listeval.core/eval7976 (form-init4504441070457356195.clj:1)
Does the problem here lie in the code, or in how I call the function and pass an argument? In either case, how can I make this work as intended?
This happens because (1 ..) is treated as calling a function, and 1 is a Long, and not a function. First you should change the nested list to '(1(2 3("a" 5(3)))). Next you can change your function to run recursively:
(defn list-eval
[x]
(if (list? x)
(for [lst x] (list-eval lst))
(if (integer? x)
(println "")
(println "This list contains a non-numeric value"))))
=> (list-eval '(1(2 3("a" 5(3)))))
There is a cool function called tree-seq that does all the hard work for you in traversing the structure. Use it then remove any collections, remove all numbers, and check if there is anything left.
(defn any-non-numbers?
[x]
(->> x
(tree-seq coll? #(if (map? %) (vals %) %))
(remove (some-fn coll? number?))
not-empty
boolean))
Examples:
user=> (any-non-numbers? 1)
false
user=> (any-non-numbers? [1 2])
false
user=> (any-non-numbers? [1 2 "sd"])
true
user=> (any-non-numbers? [1 2 "sd" {:x 1}])
true
user=> (any-non-numbers? [1 2 {:x 1}])
false
user=> (any-non-numbers? [1 2 {:x 1 :y "hello"}])
true
If you want to consider map keys as well, just change (vals %) to (interleave (keys %) (vals %)).
quoting
As others have mentioned, you need to quote a list to keep it from being evaluated as
code. That's the cause of the exception you're seeing.
for and nesting
for will only descend to the nesting depth you tell it to. It is not a for loop,
as you might expect, but a sequence comprehension, like the the python list comprehension.
(for [x xs, y ys] y) will presume that xs is a list of lists and flatten it.
(for [x xs, y ys, z zs] z) Is the same but with an extra level of nesting.
To walk down to any depth, you'd usually use recursion.
(There are ways to do this iteratively, but they're more difficult to wrap your head around.)
side effects
You're doing side effects (printing) inside a lazy sequence. This will work at the repl,
but if you're not using the result anywhere, it won't run and cause great confusion.
It's something every new clojurian bumps into at some point.
(doseq is like for, but for side effects.)
The clojure way is to separate functions that work with values from functions that
"do stuff", like printing to the console of launching missiles, and to keep the
side effecting functions as simple as possible.
putting it all together
Let's make a clear problem statement: Is there a non number anywhere inside an
arbitrarily nested list? If there is, print a message saying that to the console.
In a lot of cases, when you'd use a for loop in other langs reduce is what you want in clojure.
(defn collect-nested-non-numbers
;; If called with one argument, call itself with empty accumulator
;; and that argument.
([form] (collect-nested-non-numbers [] form))
([acc x]
(if (coll? x)
;; If x is a collection, use reduce to call itself on every element.
(reduce collect-nested-non-numbers acc x)
;; Put x into the accumulator if it's a non-number
(if (number? x)
acc
(conj acc x)))))
;; A function that ends in a question mark is (by convention) one that
;; returns a boolean.
(defn only-numbers? [form]
(empty? (collect-nested-non-numbers form)))
;; Our function that does stuff becomes very simple.
;; Which is a good thing, cause it's difficult to test.
(defn warn-on-non-numbers [form]
(when-not (only-numbers? form)
(println "This list contains a non-numeric value")))
And that'll work. There already exists a bunch of things that'll help you walk a nested structure, though, so you don't need to do it manually.
There's the clojure.walk namespace that comes with clojure. It's for when you have
a nested thing and want to transform some parts of it. There's tree-seq which is explained
in another answer. Specter is a library which is
a very powerful mini language for expressing transformations of nested structures.
Then there's my utils library comfy which contains reduce versions of the
functions in clojure.walk, for when you've got a nested thing and want to "reduce" it to a single value.
The nice thing about that is that you can use reduced which is like the imperative break statement, but for reduce. If it finds a non-number it doesn't need to keep going through the whole thing.
(ns foo.core
(:require
[madstap.comfy :as comfy]))
(defn only-numbers? [form]
(comfy/prewalk-reduce
(fn [ret x]
(if (or (coll? x) (number? x))
ret
(reduced false)))
true
form))
Maybe by "any item in the list (not in function position)" you meant this?
(defn only-numbers-in-arg-position? [form]
(comfy/prewalk-reduce
(fn [ret x]
(if (and (list? x) (not (every? (some-fn number? list?) (rest x))))
(reduced false)
ret))
true
form))

How to print each elements of a hash map list using map function in clojure?

I am constructing a list of hash maps which is then passed to another function. When I try to print each hash maps from the list using map it is not working. I am able to print the full list or get the first element etc.
(defn m [a]
(println a)
(map #(println %) a))
The following works from the repl only.
(m (map #(hash-map :a %) [1 2 3]))
But from the program that I load using load-file it is not working. I am seeing the a but not its individual elements. What's wrong?
In Clojure tranform functions return a lazy sequence. So, (map #(println %) a) return a lazy sequence. When consumed, the map action is applied and only then the print-side effect is visible.
If the purpose of the function is to have a side effect, like printing, you need to eagerly evaluate the transformation. The functions dorun and doall
(def a [1 2 3])
(dorun (map #(println %) a))
; returns nil
(doall (map #(println %) a))
; returns the collection
If you actually don't want to map, but only have a side effect, you can use doseq. It is intended to 'iterate' to do side effects:
(def a [1 2 3])
(doseq [i a]
(println i))
If your goal is simply to call an existing function on every item in a collection in order, ignoring the returned values, then you should use run!:
(run! println [1 2 3])
;; 1
;; 2
;; 3
;;=> nil
In some more complicated cases it may be preferable to use doseq as #Gamlor suggests, but in this case, doseq only adds boilerplate.
I recommend to use tail recursion:
(defn printList [a]
(let [head (first a)
tail (rest a)]
(when (not (nil? head))
(println head)
(printList tail))))

How to make '() to be nil?

How to make clojure to count '() as nil?
For example:
How to make something like
(if '() :true :false)
;to be
:false
;Or easier
(my-fun/macro/namespace/... (if '() :true :false))
:false
And not just if. In every way.
(= nil '()) or (my-something (= nil '()))
true
And every code to be (= '() nil) save.
(something (+ 1 (if (= nil '()) 1 2)))
2
I was thinking about some kind of regural expression. Which will look on code and replace '() by nil, but there are some things like (rest '(1)) and many others which are '() and I am not sure how to handle it.
I was told that macros allow you to build your own languages. I want to try it by changing clojure. So this is much about "How clojure works and how to change it?" than "I really need it to for my work."
Thank you for help.
'() just isn't the same thing as nil - why would you want it do be?
What you might be looking for though is the seq function, which returns nil if given an empty collection:
(seq [1 2 3])
=> (1 2 3)
(seq [])
=> nil
(seq '())
=> nil
seq is therefore often used to test for "emptiness", with idioms like:
(if (seq coll)
(do-something-with coll)
(get-empty-result))
You say you would like to change Clojure using the macros. Presently, as far as I know, this is not something you could do with the "regular" macro system (terminology fix anyone?). What you would really need (I think) is a reader macro. Things I have seen online (here, for example) seem to say that there exists something like reader macros in Clojure 1.4--but I have no familiarity with this because I really like using clooj as my IDE, and it currently is not using Clojure 1.4. Maybe somebody else has better info on this "extensible reader" magic.
Regardless, I don't really like the idea of changing the language in that way, and I think there is a potentially very good alternative: namely, the Clojure function not-empty.
This function takes any collection and either returns that collection as is, or returns nil if that collection is empty. This means that anywhere you will want () to return nil, you should wrap it not-empty. This answer is very similar to mikera's answer above, except that you don't have to convert your collections to sequences (which can be nice).
Both using seq and not-empty are pretty silly in cases where you have a "hand-written" collection. After all, if you are writing it by hand (or rather, typing it manually), then you are going to know for sure whether or not it is empty. The cases in which this is useful is when you have an expression or a symbol that returns a collection, and you do not know whether the returned collection will be empty or not.
Example:
=> (if-let [c (not-empty (take (rand-int 5) [:a :b :c :d]))]
(println c)
(println "Twas empty"))
;//80% of the time, this will print some non-empty sub-list of [:a :b :c :d]
;//The other 20% of the time, this will return...
Twas empty
=> nil
What about empty? ? It's the most expressive.
(if (empty? '())
:true
:false)
You can override macros and functions. For instance:
(defn classic-lisp [arg]
(if (seq? arg) (seq arg) arg))
(defn = [& args]
(apply clojure.core/= (map classic-lisp args)))
(defmacro when [cond & args]
`(when (classic-lisp ~cond) ~#args))
Unfortunately, you can't override if, as it is a special form and not a macro. You will have to wrap your code with another macro.
Let's make an if* macro to be an if with common-lisp behavior:
(defmacro if* [cond & args]
`(if (classic-lisp ~cond) ~#args)
With this, we can replace all ifs with if*s:
(use 'clojure.walk)
(defn replace-ifs [code]
(postwalk-replace '{if if*} (macroexpand-all code)))
(defmacro clojure-the-old-way [& body]
`(do ~#(map replace-ifs body)))
Now:
=> (clojure-the-old-way (if '() :true :false) )
:false
You should be able to load files and replace ifs in them too:
(defn read-clj-file [filename]
;; loads list of clojure expressions from file *filename*
(read-string (str "(" (slurp filename) ")")))
(defn load-clj-file-the-old-way [filename]
(doseq [line (replace-ifs (read-clj-file filename))] (eval line))
Note that I didn't test the code to load files and it might be incompatible with leiningen or namespaces. I believe it should work with overriden = though.

How to evaluate a sequence of impure functions in Clojure?

How can I evaluate a list of (impure) functions in Clojure? For instance:
[#(println "1") #(println "2") #(println "3")]
The expected output is:
1
2
3
Is there a way to achieve this without using macros? Something like (map evaluate fns-seq), maybe?
(I need this for drawing some graphics using the Clojure.processing API.)
user> (let [fs [#(println "1") #(println "2") #(println "3")]]
(doseq [f fs] (f)))
1
2
3
nil
This will eagerly consume the whole seq, calling all functions for side effects and returning whatever the last one returns:
(reduce #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns nil
If you want to hold onto the return values, you can use reductions instead:
(reductions #(%2) nil [#(println :foo) #(println :bar)])
; => prints :foo, then :bar, then returns (nil nil)
reductions is found in clojure.contrib.seq-utils in Clojure 1.1 and in clojure.core in current snapshots of 1.2.
Update: Note that reductions returns a lazy seq, so it's no improvement over map (NB. in map you'd want to use #(%) rather than #(%2)). I mentioned it here mostly for completeness. In fact, I posted the whole answer for completeness, because normally I'd go with the doseq approach (see Brian's answer).
(apply pcalls [#(println "1") #(println "2") #(println "3")]) does just that. Just be wary of pcalls' parallelism (therefore lack of sequentiality) and lazyness.
An old question, I know, but there's another option.
You could simply invoke the functions:
(defn generate-fns []
[#(println "1") #(println "2") #(println "3")])
(dorun (pmap (memfn invoke) (generate-fns)))
This allows you to decide in a different context how you would like to execute the functions (say, pmap, or claypoole's upmap for example)

Clojure apply vs map

I have a sequence (foundApps) returned from a function and I want to map a function to all it's elements. For some reason, apply and count work for the sequnece but map doesn't:
(apply println foundApps)
(map println rest foundApps)
(map (fn [app] (println app)) foundApps)
(println (str "Found " (count foundApps) " apps to delete"))))
Prints:
{:description another descr, :title apptwo, :owner jim, :appstoreid 1235, :kind App, :key #<Key App(2)>} {:description another descr, :title apptwo, :owner jim, :appstoreid 1235, :kind App, :key #<Key App(4)>}
Found 2 apps to delete for id 1235
So apply seems to happily work for the sequence, but map doesn't. Where am I being stupid?
I have a simple explanation which this post is lacking. Let's imagine an abstract function F and a vector. So,
(apply F [1 2 3 4 5])
translates to
(F 1 2 3 4 5)
which means that F has to be at best case variadic.
While
(map F [1 2 3 4 5])
translates to
[(F 1) (F 2) (F 3) (F 4) (F 5)]
which means that F has to be single-variable, or at least behave this way.
There are some nuances about types, since map actually returns a lazy sequence instead of vector. But for the sake of simplicity, I hope it's pardonable.
Most likely you're being hit by map's laziness. (map produces a lazy sequence which is only realised when some code actually uses its elements. And even then the realisation happens in chunks, so that you have to walk the whole sequence to make sure it all got realised.) Try wrapping the map expression in a dorun:
(dorun (map println foundApps))
Also, since you're doing it just for the side effects, it might be cleaner to use doseq instead:
(doseq [fa foundApps]
(println fa))
Note that (map println foundApps) should work just fine at the REPL; I'm assuming you've extracted it from somewhere in your code where it's not being forced. There's no such difference with doseq which is strict (i.e. not lazy) and will walk its argument sequences for you under any circumstances. Also note that doseq returns nil as its value; it's only good for side-effects. Finally I've skipped the rest from your code; you might have meant (rest foundApps) (unless it's just a typo).
Also note that (apply println foundApps) will print all the foundApps on one line, whereas (dorun (map println foundApps)) will print each member of foundApps on its own line.
A little explanation might help. In general you use apply to splat a sequence of elements into a set of arguments to a function. So applying a function to some arguments just means passing them in as arguments to the function, in a single function call.
The map function will do what you want, create a new seq by plugging each element of the input into a function and then storing the output. It does it lazily though, so the values will only be computed when you actually iterate over the list. To force this you can use the (doall my-seq) function, but most of the time you won't need to do that.
If you need to perform an operation immediately because it has side effects, like printing or saving to a database or something, then you typically use doseq.
So to append "foo" to all of your apps (assuming they are strings):
(map (fn [app] (str app "foo")) found-apps)
or using the shorhand for an anonymous function:
(map #(str % "foo") found-apps)
Doing the same but printing immediately can be done with either of these:
(doall (map #(println %) found-apps))
(doseq [app found-apps] (println app))