counting function calls in clojure - clojure

Hi I am looking for a method to count function calls in clojure so that for instance I can find out which functions are called most frequently. Ideally I would like this to be transparent to users so that if they add a function they don't know or care about this process. Any help would be greatly appreciated.
Thanking you in advance
Michael

You can store the call count in an atom and attach an accessor to the function using with-meta:
(def sqrt
(let [n (atom 0)]
(with-meta
(fn [x]
(swap! n inc)
(Math/sqrt x))
{::call-count (fn [] #n)})))
Examples:
((::call-count (meta sqrt))) ;=> 0
(sqrt 0) ;=> 0.0
(sqrt 1) ;=> 1.0
(sqrt 2) ;=> 1.4142135623730951
((::call-count (meta sqrt))) ;=> 3
(sqrt 3) ;=> 1.7320508075688772
(sqrt 4) ;=> 2.0
(sqrt 5) ;=> 2.23606797749979
((::call-count (meta sqrt))) ;=> 6
This may cause considerable slowdown in some cases, but the count will always be updated correctly because Clojure atoms are thread-safe. Another approach could be to use add-watch rather than deref, but which one is better depends on your situation. You could even use both if you want to.
You can abstract away the details with a defcounted macro to define call-counted functions and a call-count function to retrieve the call count of a call-counted function:
(defmacro defcounted [sym params & body]
`(def ~sym
(let [n# (atom 0)]
(with-meta
(fn ~params
(swap! n# inc)
~#body)
{::call-count (fn [] #n#)}))))
(defn call-count [f]
((::call-count (meta f))))
(defcounted sqrt [x]
(Math/sqrt x))
Examples:
(call-count sqrt) ;=> 0
(sqrt 0) ;=> 0.0
(sqrt 1) ;=> 1.0
(sqrt 2) ;=> 1.4142135623730951
(call-count sqrt) ;=> 3
(sqrt 3) ;=> 1.7320508075688772
(sqrt 4) ;=> 2.0
(sqrt 5) ;=> 2.23606797749979
(call-count sqrt) ;=> 6
Also, since here you're attaching the metadata to the function itself rather than to the var, you could expand this technique to anonymous functions as well.
Obviously defcounted is lacking a lot of defn's features, so it's not really transparent to the user. In fixing this problem, you could use clojure.spec to more easily parse the defn-style arguments, but I'll leave that for you to do as you see fit, as it's orthogonal to this question.

Related

Higher-order if-then-else in Clojure?

I often have to run my data through a function if the data fulfill certain criteria. Typically, both the function f and the criteria checker pred are parameterized to the data. For this reason, I find myself wishing for a higher-order if-then-else which knows neither f nor pred.
For example, assume I want to add 10 to all even integers in (range 5). Instead of
(map #(if (even? %) (+ % 10) %) (range 5))
I would prefer to have a helper –let's call it fork– and do this:
(map (fork even? #(+ % 10)) (range 5))
I could go ahead and implement fork as function. It would look like this:
(defn fork
([pred thenf elsef]
#(if (pred %) (thenf %) (elsef %)))
([pred thenf]
(fork pred thenf identity)))
Can this be done by elegantly combining core functions? Some nice chain of juxt / apply / some maybe?
Alternatively, do you know any Clojure library which implements the above (or similar)?
As Alan Thompson mentions, cond-> is a fairly standard way of implicitly getting the "else" part to be "return the value unchanged" these days. It doesn't really address your hope of being higher-order, though. I have another reason to dislike cond->: I think (and argued when cond-> was being invented) that it's a mistake for it to thread through each matching test, instead of just the first. It makes it impossible to use cond-> as an analogue to cond.
If you agree with me, you might try flatland.useful.fn/fix, or one of the other tools in that family, which we wrote years before cond->1.
to-fix is exactly your fork, except that it can handle multiple clauses and accepts constants as well as functions (for example, maybe you want to add 10 to other even numbers but replace 0 with 20):
(map (to-fix zero? 20, even? #(+ % 10)) xs)
It's easy to replicate the behavior of cond-> using fix, but not the other way around, which is why I argue that fix was the better design choice.
1 Apparently we're just a couple weeks away from the 10-year anniversary of the final version of fix. How time flies.
I agree that it could be very useful to have some kind of higher-order functional construct for this but I am not aware of any such construct. It is true that you could implement a higher order fork function, but its usefulness would be quite limited and can easily be achieved using if or the cond-> macro, as suggested in the other answers.
What comes to mind, however, are transducers. You could fairly easily implement a forking transducer that can be composed with other transducers to build powerful and concise sequence processing algorithms.
The implementation could look like this:
(defn forking [pred true-transducer false-transducer]
(fn [step]
(let [true-step (true-transducer step)
false-step (false-transducer step)]
(fn
([] (step))
([dst x] ((if (pred x) true-step false-step) dst x))
([dst] dst))))) ;; flushing not performed.
And this is how you would use it in your example:
(eduction (forking even?
(map #(+ 10 %))
identity)
(range 20))
;; => (10 1 12 3 14 5 16 7 18 9 20 11 22 13 24 15 26 17 28 19)
But it can also be composed with other transducers to build more complex sequence processing algorithms:
(into []
(comp (forking even?
(comp (drop 4)
(map #(+ 10 %)))
(comp (filter #(< 10 %))
(map #(vector % % %))
cat))
(partition-all 3))
(range 20))
;; => [[18 20 11] [11 11 22] [13 13 13] [24 15 15] [15 26 17] [17 17 28] [19 19 19]]
Another way to define fork (with three inputs) could be:
(defn fork [pred then else]
(comp
(partial apply apply)
(juxt (comp {true then, false else} pred) list)))
Notice that in this version the inputs and output can receive zero or more arguments. But let's take a more structured approach, defining some other useful combinators. Let's start by defining pick which corresponds to the categorical coproduct (sum) of morphisms:
(defn pick [actions]
(fn [[tag val]]
((actions tag) val)))
;alternatively
(defn pick [actions]
(comp
(partial apply apply)
(juxt (comp actions first) rest)))
E.g. (mapv (pick [inc dec]) [[0 1] [1 1]]) gives [2 0]. Using pick we can define switch which works like case:
(defn switch [test actions]
(comp
(pick actions)
(juxt test identity)))
E.g. (mapv (switch #(mod % 3) [inc dec -]) [3 4 5]) gives [4 3 -5]. Using switch we can easily define fork:
(defn fork [pred then else]
(switch pred {true then, false else}))
E.g. (mapv (fork even? inc dec) [0 1]) gives [1 0]. Finally, using fork let's also define fork* which receives zero or more predicate and action pairs and works like cond:
(defn fork* [& args]
(->> args
(partition 2)
reverse
(reduce
(fn [else [pred then]]
(fork pred then else))
identity)))
;equivalently
(defn fork* [& args]
(->> args
(partition 2)
(map (partial apply (partial partial fork)))
(apply comp)
(#(% identity))))
E.g. (mapv (fork* neg? -, even? inc) [-1 0 1]) gives [1 1 1].
Depending on the details, it is often easiest to accomplish this goal using the cond-> macro and friends:
(let [myfn (fn [val]
(cond-> val
(even? val) (+ val 10))) ]
with result
(mapv myfn (range 5)) => [10 1 14 3 18]
There is a variant in the Tupelo library that is sometimes helpful:
(mapv #(cond-it-> %
(even? it) (+ it 10))
(range 5))
that allows you to use the special symbol it as you thread the value through multiple stages.
As the examples show, you have the option to define and name the transformer function (my favorite), or use the function literal syntax #(...)

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.

setf in Clojure

I know I can do the following in Common Lisp:
CL-USER> (let ((my-list nil))
(dotimes (i 5)
(setf my-list (cons i my-list)))
my-list)
(4 3 2 1 0)
How do I do this in Clojure? In particular, how do I do this without having a setf in Clojure?
My personal translation of what you are doing in Common Lisp would Clojurewise be:
(into (list) (range 5))
which results in:
(4 3 2 1 0)
A little explanation:
The function into conjoins all elements to a collection, here a new list, created with (list), from some other collection, here the range 0 .. 4. The behavior of conj differs per data structure. For a list, conj behaves as cons: it puts an element at the head of a list and returns that as a new list. So what is does is this:
(cons 4 (cons 3 (cons 2 (cons 1 (cons 0 (list))))))
which is similar to what you are doing in Common Lisp. The difference in Clojure is that we are returning new lists all the time, instead of altering one list. Mutation is only used when really needed in Clojure.
Of course you can also get this list right away, but this is probably not what you wanted to know:
(range 4 -1 -1)
or
(reverse (range 5))
or... the shortest version I can come up with:
'(4 3 2 1 0)
;-).
Augh the way to do this in Clojure is to not do it: Clojure hates mutable state (it's available, but using it for every little thing is discouraged). Instead, notice the pattern: you're really computing (cons 4 (cons 3 (cons 2 (cons 1 (cons 0 nil))))). That looks an awful lot like a reduce (or a fold, if you prefer). So, (reduce (fn [acc x] (cons x acc)) nil (range 5)), which yields the answer you were looking for.
Clojure bans mutation of local variables for the sake of thread safety, but it is still possible to write loops even without mutation. In each run of the loop you want to my-list to have a different value, but this can be achieved with recursion as well:
(let [step (fn [i my-list]
(if (< i 5)
my-list
(recur (inc i) (cons i my-list))))]
(step 0 nil))
Clojure also has a way to "just do the looping" without making a new function, namely loop. It looks like a let, but you can also jump to beginning of its body, update the bindings, and run the body again with recur.
(loop [i 0
my-list nil]
(if (< i 5)
my-list
(recur (inc i) (cons i my-list))))
"Updating" parameters with a recursive tail call can look very similar to mutating a variable but there is one important difference: when you type my-list in your Clojure code, its meaning will always always the value of my-list. If a nested function closes over my-list and the loop continues to the next iteration, the nested function will always see the value that my-list had when the nested function was created. A local variable can always be replaced with its value, and the variable you have after making a recursive call is in a sense a different variable.
(The Clojure compiler performs an optimization so that no extra space is needed for this "new variable": When a variable needs to be remembered its value is copied and when recur is called the old variable is reused.)
For this I would use range with the manually set step:
(range 4 (dec 0) -1) ; => (4 3 2 1 0)
dec decreases the end step with 1, so that we get value 0 out.
user=> (range 5)
(0 1 2 3 4)
user=> (take 5 (iterate inc 0))
(0 1 2 3 4)
user=> (for [x [-1 0 1 2 3]]
(inc x)) ; just to make it clear what's going on
(0 1 2 3 4)
setf is state mutation. Clojure has very specific opinions about that, and provides the tools for it if you need it. You don't in the above case.
(let [my-list (atom ())]
(dotimes [i 5]
(reset! my-list (cons i #my-list)))
#my-list)
(def ^:dynamic my-list nil);need ^:dynamic in clojure 1.3
(binding [my-list ()]
(dotimes [i 5]
(set! my-list (cons i my-list)))
my-list)
This is the pattern I was looking for:
(loop [result [] x 5]
(if (zero? x)
result
(recur (conj result x) (dec x))))
I found the answer in Programming Clojure (Second Edition) by Stuart Halloway and Aaron Bedra.

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 list (seq) traversal to compare items to other items

Say I have a list (a b c d e), I'm trying to figure out a "lazy" and Clojure-idiomatic way of producing a list or seq of each item with each other item, such as ((a b) (a c) (a d) (a e) (b c) (b d) (b e) (c d) (c e) (d e)).
Clojure's for doesn't seem to allow this, it just produces one item as it goes through a list and doesn't allow access to a sub-list. The closest I've come so far is to turn the original list into a vector, and have a for statement that iterates over the count of the vector and grab indexed items,
(for [i (range vector-count) j (range i vector-count)]
...
but I hope that there's a better way.
You want combinations. There's a function to give you a lazy sequence of combinations right here in clojure-contrib.
user> (combinations [:a :b :c :d :e] 2)
((:a :b) (:a :c) (:a :d) (:a :e) (:b :c) (:b :d) (:b :e) (:c :d) (:c :e) (:d :e))
(Unfortunately, the monolithic clojure-contrib repo containing that file is deprecated in favor of splitting contrib up into smaller separate repos, and clojure.contrib.combinatorics doesn't seem to have made the transition yet, so there's no easy way currently to install that library, but you can snag the code from github if nothing else.)
FWIW, I tried writing this without looking at the code in contrib. I think my code is much easier to understand, and in my simple-minded benchmark it's more than twice as fast. It's available at https://gist.github.com/1042047, and reproduced below for convenience:
(defn combinations [n coll]
(if (= 1 n)
(map list coll)
(lazy-seq
(when-let [[head & tail] (seq coll)]
(concat (for [x (combinations (dec n) tail)]
(cons head x))
(combinations n tail))))))
user> (require '[clojure.contrib.combinatorics :as combine])
nil
user> (time (last (user/combinations 4 (range 100))))
"Elapsed time: 4379.959957 msecs"
(96 97 98 99)
user> (time (last (combine/combinations (range 100) 4)))
"Elapsed time: 10913.170605 msecs"
(96 97 98 99)
I strongly prefer the [n coll] argument order, rather than [coll n] - clojure likes the "important" argument to come last, especially for functions dealing with seqs: mostly this is for ease of combination with (->>) in scenarios like (->> (my-list) (filter even?) (take 10) (combinations 8)).
why use range and index grabbing in the for loop?
(let [myseq (list :a :b :c :d)]
(for [a myseq b myseq] (list a b)))
works.