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)
Related
I am learning clojurescript and i came across this snippet.
:on-click (fn [] (swap! state/order update (:id gig) inc))
I looked up the docs for update function and it said that update takes in a key and a functions. Passes the old value from the atom to the function and then update the atom. If there is no existing value for the key in atom nil is passed as input to the function.
When i tried the same thing in the repl it did not work
(def atom-test (atom {}))
(swap! atom-test update :aa inc)
NullPointerException clojure.lang.Numbers.ops (Numbers.java:1013)
Adding fnil to catch this NullPointerException worked.
user=> (swap! atom-test update :aa (fnil inc 0))
{:aa 1}
I cannot understand why it works in case 1 in clojurescript and why it does not work in case 2 in clojure repl. Can anyone explain whats the trick here.
For cljs, it is common for operations to safely handle nil without causing exceptions.
cljs.user=> (update {} :a inc)
{:a 1}
cljs.user=> (inc nil)
1
cljs.user=> (+ 1 nil)
1
https://cljs.github.io/api/syntax/nil
The inc function requires an argument that satisfies number?. This is true in Clojure and ClojureScript.
If you pass something else, like nil, the program is incorrect: (inc nil) has undefined behavior. This is not safe to do. It just so happens to return 1 but that is not guaranteed and is an accident of implementation.
If, for example, you instead pass a literal string to inc, ClojureScript will emit a warning at compile time:
cljs.user=> (inc "a")
WARNING: cljs.core/+, all arguments must be numbers, got [string number] instead at line 1 <cljs repl>
Perhaps in the future, the compiler could similarly emit a warning for (inc nil), but what is more likely to happen is that specs will be written covering core functions, with cljs.core/inc being specified to accept an argument satisfying number?.
TL;DR: using fnil is the correct thing to do here.
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
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.
I'm trying to understand when clojure's lazy sequences are lazy, and when the work happens, and how I can influence those things.
user=> (def lz-seq (map #(do (println "fn call!") (identity %)) (range 4)))
#'user/lz-seq
user=> (let [[a b] lz-seq])
fn call!
fn call!
fn call!
fn call!
nil
I was hoping to see only two "fn call!"s here. Is there a way to manage that?
Anyway, moving on to something which indisputably only requires one evaluation:
user=> (def lz-seq (map #(do (println "fn call!") (identity %)) (range 4)))
#'user/lz-seq
user=> (first lz-seq)
fn call!
fn call!
fn call!
fn call!
0
Is first not suitable for lazy sequences?
user=> (def lz-seq (map #(do (println "fn call!") (identity %)) (range 4)))
#'user/lz-seq
user=> (take 1 lz-seq)
(fn call!
fn call!
fn call!
fn call!
0)
At this point, I'm completely at a loss as to how to access the beginning of my toy lz-seq without having to realize the entire thing. What's going on?
Clojure's sequences are lazy, but for efficiency are also chunked, realizing blocks of 32 results at a time.
=>(def lz-seq (map #(do (println (str "fn call " %)) (identity %)) (range 100)))
=>(first lz-seq)
fn call 0
fn call 1
...
fn call 31
0
The same thing happens once you cross the 32 boundary first
=>(nth lz-seq 33)
fn call 0
fn call 1
...
fn call 63
33
For code where considerable work needs to be done per realisation, Fogus gives a way to work around chunking, and gives a hint an official way to control chunking might be underway.
I believe that the expression produces a chunked sequence. Try replacing 4 with 10000 in the range expression - you'll see something like 32 calls on first eval, which is the size of the chunk.
A lazy sequence is one where we evaluate the sequence as and when needed. (hence lazy). Once a result is evaluated, it is cached so that it can be re-used (and we don't have to do the work again). If you try to realize an item of the sequence that hasn't been evaluated yet, clojure evaluates it and returns the value to you. However, it also does some extra work. It anticipates that you might want to evaluate the next element(s) in the sequence and does that for you too. This is done to avoid some performance overheads, the exact nature of which is beyond my skill-level. Thus, when you say (first lz-seq), it actually calculates the first as well as the next few elements in the seq. Since your println statement is a side effect, you can see the evaluation happening. Now if you were to say (second lz-seq), you will not see the println again since the result has already been evaluated and cached.
A better way to see that your sequence is lazy is :
user=> def lz-seq (map #(do (println "fn call!") (identity %)) (range 400))
#'user/lz-seq
user=> (first lz-seq)
This will print a few "fn call!" statements, but not all 400 of them. That's because the first call will actually end up evaluating more than one element of the sequence.
Hope this explanation is clear enough.
I think its some sort of optimization made by repl.
My repl is caching 32 at a time.
user=> (def lz-seq (map #(do (println "fn call!") (identity %)) (range 100))
#'user/lz-seq
user=> (first lz-seq)
prints 32 times
user=> (take 20 lz-seq)
does not print any "fn call!"
user=> (take 33 lz-seq)
prints 0 to 30, then prints 32 more "fn call!"s followed by 31,32
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))