clojure: (apply fn coll) vs (apply #(apply fn %&) coll) - clojure

I am working my way through labrepl and I saw some code that follows this pattern:
;; Pattern
(apply #(apply f %&) coll)
;; Concrete example
user=> (apply #(apply + %&) [1 2 3 4])
10
This seems to be equivalent to this pattern:
;; Pattern
(apply f coll)
;; Concrete example
user=> (apply + [1 2 3 4])
10
Are these patterns equivalent? If not, what's the difference and when would you use one over the other?
I took the former pattern from the step function in the cellular-automata lab of labrepl:
(defn step
"Advance the automation by one step, updating all cells."
[board]
(doall
(map (fn [window]
(apply #(apply map brians-brain-rules %&)
(doall (map torus-window window))))
(torus-window board))))
Update: I added a concrete example of each pattern to help make the question clearer.

No, there is no difference. There is no reason to write the longer form; I can only assume it was arrived at by gradual changes to code that made sense at one time.

Essentially, both forms accomplish the same thing and are more or less the same. Each provides a way to introduce an anonymous function.
Using #(... is a Clojure reader shorthand for an anonymous function. It is kind of equivalent to (fn [arg1 & args]... , but you cannot embed one #(... anonymous function inside another, and arguments are expressed as % %2... or %1 %2... rather than with vector binding (fn [arg & args].
Both are methods to express an anonymous function. #(... is used for simpler functions, and (fn... is used for more detailed functions.
#(... tends to make things look a little neater.

Related

Clojure: Combining a vector of univariate functions with a vector of arguments [duplicate]

I want to pairwise apply a list of functions to a list of values.
Here's an example to illustrate.
user=> (defn a [f x] (f x))
#'user/a
user=> (map a [inc dec] '(98 8))
(99 7)
Notice I had to define a function a that takes a function and applies it to a value. Basically abstracting function application.
Is there a more natural way to do this? I would really just like to use map with defining a helper function.
You can always define functions anonymously, inline:
(map (fn [f x] (f x)) [inc dec] '(98 8))
or shorter, using the #() reader macro:
(map #(%1 %2) [inc dec] '(98 8))
It's a fairly awkward use case though, so I doubt you can reduce it to something shorter using just core clojure or clojure.contrib, but you can easily write your own abstraction:
(defn mapfs [fs coll] (map #(%1 %2) fs coll))
(mapfs [inc dec] [98 8])
> (99 7)
If you're willing to slightly modify the format of your values, things get a bit simpler:
user=> (map apply [inc dec] [[98] [8]])
(99 7)
It's necessary because apply must have a seq as its last argument. This transformation ([98 8] => [[98] [8]]) feels like a reasonable thing to do anyway, since otherwise you depend on the fact that the functions may only take one value apiece. It's of course trivial to do:
user=> (map list [98 8])
((98) (8))
Otherwise, Joost's mapping function #(%1 %2) is as concise as you're going to get.

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

What is the difference between the reader monad and a partial function in Clojure?

Leonardo Borges has put together a fantastic presentation on Monads in Clojure. In it he describes the reader monad in Clojure using the following code:
;; Reader Monad
(def reader-m
{:return (fn [a]
(fn [_] a))
:bind (fn [m k]
(fn [r]
((k (m r)) r)))})
(defn ask [] identity)
(defn asks [f]
(fn [env]
(f env)))
(defn connect-to-db []
(do-m reader-m
[db-uri (asks :db-uri)]
(prn (format "Connected to db at %s" db-uri))))
(defn connect-to-api []
(do-m reader-m
[api-key (asks :api-key)
env (ask)]
(prn (format "Connected to api with key %s" api-key))))
(defn run-app []
(do-m reader-m
[_ (connect-to-db)
_ (connect-to-api)]
(prn "Done.")))
((run-app) {:db-uri "user:passwd#host/dbname" :api-key "AF167"})
;; "Connected to db at user:passwd#host/dbname"
;; "Connected to api with key AF167"
;; "Done."
The benefit of this is that you're reading values from the environment in a purely functional way.
But this approach looks very similar to the partial function in Clojure. Consider the following code:
user=> (def hundred-times (partial * 100))
#'user/hundred-times
user=> (hundred-times 5)
500
user=> (hundred-times 4 5 6)
12000
My question is: What is the difference between the reader monad and a partial function in Clojure?
The reader monad is a set of rules we can apply to cleanly compose readers. You could use partial to make a reader, but it doesn't really give us a way to put them together.
For example, say you wanted a reader that doubled the value it read. You might use partial to define it:
(def doubler
(partial * 2))
You might also want a reader that added one to whatever value it read:
(def plus-oner
(partial + 1))
Now, suppose you wanted to combine these guys in a single reader that adds their results. You'll probably end up with something like this:
(defn super-reader
[env]
(let [x (doubler env)
y (plus-oner env)]
(+ x y)))
Notice that you have to explicitly forward the environment to those readers. Total bummer, right? Using the rules provided by the reader monad, we can get much cleaner composition:
(def super-reader
(do-m reader-m
[x doubler
y plus-oner]
(+ x y)))
You can use partial to "do" the reader monad. Turn let into a do-reader by doing syntactic transformation on let with partial application of the environment on the right-hand side.
(defmacro do-reader
[bindings & body]
(let [env (gensym 'env_)
partial-env (fn [f] (list `(partial ~f ~env)))
bindings* (mapv #(%1 %2) (cycle [identity partial-env]) bindings)]
`(fn [~env] (let ~bindings* ~#body))))
Then do-reader is to the reader monad as let is to the identity monad (relationship discussed here).
Indeed, since only the "do notation" application of the reader monad was used in Beyamor's answer to your reader monad in Clojure question, the same examples will work as is with m/domonad Reader replaced with do-reader as above.
But, for the sake of variety I'll modify the first example to be just a bit more Clojurish with the environment map and take advantage of the fact that keywords can act as functions.
(def sample-bindings {:count 3, :one 1, :b 2})
(def ask identity)
(def calc-is-count-correct?
(do-reader [binding-count :count
bindings ask]
(= binding-count (count bindings))))
(calc-is-count-correct? sample-bindings)
;=> true
Second example
(defn local [modify reader] (comp reader modify))
(def calc-content-len
(do-reader [content ask]
(count content)))
(def calc-modified-content-len
(local #(str "Prefix " %) calc-content-len))
(calc-content-len "12345")
;=> 5
(calc-modified-content-len "12345")
;=> 12
Note since we built on let, we still have destructing at our disposal. Silly example:
(def example1
(do-reader [a :foo
b :bar]
(+ a b)))
(example1 {:foo 2 :bar 40 :baz 800})
;=> 42
(def example2
(do-reader [[a b] (juxt :foo :bar)]
(+ a b)))
(example2 {:foo 2 :bar 40 :baz 800})
;=> 42
So, in Clojure, you can indeed get the functionality of the do notation of reader monad without introducing monads proper. Analagous to doing a ReaderT transform on the identity monad, we can do a syntactic transformation on let. As you surmised, one way to do so is with partial application of the environment.
Perhaps more Clojurish would be to define a reader-> and reader->> to syntactically insert the environment as the second and last argument respectively. I'll leave those as an exercise for the reader for now.
One take-away from this is that while types and type-classes in Haskell have a lot of benefits and the monad structure is a useful idea, not having the constraints of the type system in Clojure allows us to treat data and programs in the same way and do arbitrary transformations to our programs to implement syntax and control as we see fit.

How To Define Function From Closure

This question is related to one I asked recently.
If I rewrite (fn [n] (fn [x] (apply * (repeat n x)))) as
(defn power [n] (fn [x] (apply * (repeat n x))))`
it works just fine when used like this
((power 2) 16)
I can substitute 2 with another power, but I'd like to make a function just for squares, cubed, and so on. What is the best way to do that? I've been fiddling with it in the REPL, but no luck so far.
Using a macro for this goes entirely around his question, which was "I have a function that generates closures, how do I give those closures names?" The simple solution is:
(letfn [(power [n]
(fn [x]
(apply * (repeat n x))))]
(def square (power 2))
(def cube (power 3)))
If you really truly hate repeating def and power a few times, then and only then is it time to get macros involved. But the amount of effort you'll spend on even the simplest macro will be wasted unless you're defining functions up to at least the tenth power, compared to the simplicity of doing it with functions.
Not quite sure if this is what you're searching for, but macro templates might be it. Here's how I would write your code:
(use 'clojure.template)
(do-template [name n]
(defn name [x] (apply * (repeat n x)))
square 2
cube 3)
user> (cube 3)
;=> 27
For more complex type of similar tasks, you could write a macro that wrap do-template to perform some transformation on its arguments, e.g.:
(defmacro def-powers-of [& ns]
(let [->name #(->> % (str "power") symbol)]
`(do-template [~'name ~'n]
(defn ~'name [~'x] (apply * (repeat ~'n ~'x)))
~#(->> ns
(map #(vector (->name %) %))
flatten))))
(def-powers-of 2 3 4 5)
user> (power3 3)
;=> 27
user> (power5 3)
;=> 243
P.S.: That macro might look awkward if you're just starting with Clojure though, don't give up because of it! ;-)

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