The following example in clojure calls the nullary and binary cases of + in various ways:
(println 101 (+)) ; fine
(println 102 (+ (+) 4)) ; fine
(println 103 (reduce + (+) (range 4))) ; fine
(println 104 (reduce + (range 4))) ; fine
I tried replacing + with mean-reducer as described in this blog post (warning: no https).
I changed the mean-reducer function to explicitly expose its identity element {:sum 0 :count 0} when invoked with no arguments.
This works fine for the simple cases leading up to (reduce mean-reducer (range 4)), but falls over for (reduce mean-reducer (range 4)) itself.
(defn mean-reducer
([] {:sum 0 :count 0})
([memo x]
{
:sum (+ x (memo :sum))
:count (inc (memo :count))
}))
(println 201 (mean-reducer)) ; fine
(println 202 (mean-reducer (mean-reducer) 4)) ; fine
(println 203 (reduce mean-reducer (mean-reducer) (range 4))) ; fine
;; (println 204 (reduce mean-reducer (range 4))) ; bad
runs and produces this with the last line commented.
% clojure mean_reducer.clj
201 {:sum 0, :count 0}
202 {:sum 4, :count 1}
203 {:sum 6, :count 4}
The error message and stack trace associated with the failed call to (reduce mean-reducer (range 4)) looks like this:
(~/clojure/mean_reducer.clj:12:62).
at clojure.lang.Compiler.load(Compiler.java:7647)
at clojure.lang.Compiler.loadFile(Compiler.java:7573)
at clojure.main$load_script.invokeStatic(main.clj:452)
at clojure.main$script_opt.invokeStatic(main.clj:512)
at clojure.main$script_opt.invoke(main.clj:507)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: class java.lang.Long cannot be cast to class clojure.lang.IFn (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app')
at user$mean_reducer.invokeStatic(mean_reducer.clj:5)
at user$mean_reducer.invoke(mean_reducer.clj:1)
at clojure.lang.LongRange.reduce(LongRange.java:222)
at clojure.core$reduce.invokeStatic(core.clj:6823)
at clojure.core$reduce.invoke(core.clj:6810)
at user$eval143.invokeStatic(mean_reducer.clj:13)
at user$eval143.invoke(mean_reducer.clj:13)
at clojure.lang.Compiler.eval(Compiler.java:7176)
at clojure.lang.Compiler.load(Compiler.java:7635)
... 9 more
I think this means that somehow the lines are getting crossed and an element of (range 4) is being bound to memo, but I'm not sure why this would happen given that the case with an explicit initial element succeeds.
When you pass no initial value to reduce the 2-arity version of mean-reducer is invoked with the first two elements of the range i.e. (mean-reducer 0 1). From reduce docs:
If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc.
You'll need to supply an initial value to reduce if you want to use mean-reducer (and its 0-arity won't be used). reduce has two different "contracts" for its 2-arity reducing function depending on whether an initial value is specified.
clojure.core.reducers
clojure.core.reducers/reduce has exactly the behavior you want when no initial value is supplied:
When init is not provided, (f) is used.
(r/reduce mean-reducer (range 4))
=> {:sum 6, :count 4}
Related
We've been given a task to print the first ten multiples of any number for which we have written the below code. It is throwing an error. In simple words, if n is 2 then we need to create a table of 2's till 10.
(defn multiples [n]
(while ( n < 11)
(println( n * n))
(swap! n inc)))
(def n (Integer/parseInt (clojure.string/trim (read-line))))
(multiples n)
With this, we're getting the error:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.
(defn multiples [n]
(map #(* n %) (range 1 (+ 10 1))))
user=> (multiples 1)
;; => (1 2 3 4 5 6 7 8 9 10)
user=> (multiples 2)
;; => (2 4 6 8 10 12 14 16 18 20)
The resulting list you can loop over and println each of the elements.
(for [i (multiples 2)]
(println i))
;; or:
(map println (multiples 2)) ;; though one usually doesn't apply
;; `map` on side effect functions ...
To improve your own construct:
You, coming from an imperative language, try to work with mutations.
That is very un-idiomatic clojure.
However, by declaring a value atom, you can access using the # operator to its place. And mutate the variable's value.
(defn multiples [n]
(let [i (atom 1)] ;; i is an atom
(while (< #i 11) ;; #i is the value saved into i
(println (* #i n))
(swap! i inc)))) ;; and correctly you can increase the value
With this multiples, you can also print the values.
You can't apply swap! to normal variables, only to atoms.
while loops one should apply only if number of elements not known.
In this case, one knows very well, when to stop. So use rather
a for loop.
(defn multiples [n]
(for [i (range 1 11)]
(println (* i n))))
Look at what iterate function does here
(defn multiples-of [n]
(iterate (partial * n) n))
(def ten-multiples-of-ten
(take 10 (multiples-of 10)))
EDIT: I misread the author of the question, I believe he wants to just generate a sequence of squares. Here is one way using transducers, cause why not ;)
(def xf
(comp
(map inc)
(map #(* % %))))
(defn first-n-squares [n]
(into [] xf (take n (range))))
You can use recur in a loop:
(defn multiples [n]
(if (< n 11)
(do ; then
(println (* n n))
(recur (inc n)))
nil)) ; else return nil
Running this by invoking
(multiples 1)
in a REPL will produce
1
4
9
16
25
36
49
64
81
100
nil
I'm trying to write a function with recur that cut the sequence as soon as it encounters a repetition ([1 2 3 1 4] should return [1 2 3]), this is my function:
(defn cut-at-repetition [a-seq]
(loop[[head & tail] a-seq, coll '()]
(if (empty? head)
coll
(if (contains? coll head)
coll
(recur (rest tail) (conj coll head))))))
The first problem is with the contains? that throws an exception, I tried replacing it with some but with no success. The second problem is in the recur part which will also throw an exception
You've made several mistakes:
You've used contains? on a sequence. It only works on associative
collections. Use some instead.
You've tested the first element of the sequence (head) for empty?.
Test the whole sequence.
Use a vector to accumulate the answer. conj adds elements to the
front of a list, reversing the answer.
Correcting these, we get
(defn cut-at-repetition [a-seq]
(loop [[head & tail :as all] a-seq, coll []]
(if (empty? all)
coll
(if (some #(= head %) coll)
coll
(recur tail (conj coll head))))))
(cut-at-repetition [1 2 3 1 4])
=> [1 2 3]
The above works, but it's slow, since it scans the whole sequence for every absent element. So better use a set.
Let's call the function take-distinct, since it is similar to take-while. If we follow that precedent and make it lazy, we can do it thus:
(defn take-distinct [coll]
(letfn [(td [seen unseen]
(lazy-seq
(when-let [[x & xs] (seq unseen)]
(when-not (contains? seen x)
(cons x (td (conj seen x) xs))))))]
(td #{} coll)))
We get the expected results for finite sequences:
(map (juxt identity take-distinct) [[] (range 5) [2 3 2]]
=> ([[] nil] [(0 1 2 3 4) (0 1 2 3 4)] [[2 3 2] (2 3)])
And we can take as much as we need from an endless result:
(take 10 (take-distinct (range)))
=> (0 1 2 3 4 5 6 7 8 9)
I would call your eager version take-distinctv, on the map -> mapv precedent. And I'd do it this way:
(defn take-distinctv [coll]
(loop [seen-vec [], seen-set #{}, unseen coll]
(if-let [[x & xs] (seq unseen)]
(if (contains? seen-set x)
seen-vec
(recur (conj seen-vec x) (conj seen-set x) xs))
seen-vec)))
Notice that we carry the seen elements twice:
as a vector, to return as the solution; and
as a set, to test for membership of.
Two of the three mistakes were commented on by #cfrick.
There is a tradeoff between saving a line or two and making the logic as simple & explicit as possible. To make it as obvious as possible, I would do it something like this:
(defn cut-at-repetition
[values]
(loop [remaining-values values
result []]
(if (empty? remaining-values)
result
(let [found-values (into #{} result)
new-value (first remaining-values)]
(if (contains? found-values new-value)
result
(recur
(rest remaining-values)
(conj result new-value)))))))
(cut-at-repetition [1 2 3 1 4]) => [1 2 3]
Also, be sure to bookmark The Clojure Cheatsheet and always keep a browser tab open to it.
I'd like to hear feedback on this utility function which I wrote for myself (uses filter with stateful pred instead of a loop):
(defn my-distinct
"Returns distinct values from a seq, as defined by id-getter."
[id-getter coll]
(let [seen-ids (volatile! #{})
seen? (fn [id] (if-not (contains? #seen-ids id)
(vswap! seen-ids conj id)))]
(filter (comp seen? id-getter) coll)))
(my-distinct identity "abracadabra")
; (\a \b \r \c \d)
(->> (for [i (range 50)] {:id (mod (* i i) 21) :value i})
(my-distinct :id)
pprint)
; ({:id 0, :value 0}
; {:id 1, :value 1}
; {:id 4, :value 2}
; {:id 9, :value 3}
; {:id 16, :value 4}
; {:id 15, :value 6}
; {:id 7, :value 7}
; {:id 18, :value 9})
Docs of filter says "pred must be free of side-effects" but I'm not sure if it is ok in this case. Is filter guaranteed to iterate over the sequence in order and not for example take skips forward?
Maybe this sounds ridiculous question, but it is for me still not exactly clear the difference between where the # of a anonymous function should come. For example in this example i filter the divisors of a positive number:
(filter #(zero? (mod 6 %)) (range 1 (inc 6))) ;;=> (1 2 3 6)
but putting the # right before the (mod 6 %) will cause an error. Is there a rule where in such a context my anonymous function begins, and why should the # come before (zero? ...?
This shows how the #(...) syntax is just a shorthand for (fn [x] ...):
(defn divides-6 [arg]
(zero? (mod 6 arg)))
(println (filter divides-6 (range 1 10))) ; normal function
(println (filter (fn [x] (zero? (mod 6 x))) (range 1 10))) ; anonymous function
(println (filter #(zero? (mod 6 %)) (range 1 10))) ; shorthand version
;=> (1 2 3 6)
;=> (1 2 3 6)
;=> (1 2 3 6)
Using defn is just shorthand for (def divides-6 (fn [x] ...)) (i.e. the def and fn parts are combined into defn to save a little typing). We don't need to define a global name divides-6 if we are only going to use the function once. We can just define the function inline right where it will be used. The #(...) syntax is just a shorthand version as the example shows.
Note that the full name of the form #(...) is the "anonymous function literal". You may also see it called the "function reader macro" or just the "function macro". The syntax (fn [x] ...) is called the "function special form".
Clojure's filter function takes one or two arguments; either way, the first argument must be a function. So there's no "rule" where the anonymous function is defined, as long as ultimately, the first argument to filter is a function.
However, in this case, zero? does not return a function, so (zero? #(mod 6 %)) would cause filter to throw an error. And, in fact, (zero? #(mod 6 %) doesn't make sense, either, because zero? does not take a function as an argument.
filter takes two parameters:
a predicate (a filter, which is a function), and
a collection
So, in a simple way:
(defn my-predicate [x]
(zero? (mod 6 x)))
(def my-collection
(range 1 (inc 6)))
(filter
my-filter
my-collection)
# is a clojure macro, or something that preprocess and reorganize code for you. We can see the result of a macro with macroexpand-1 :
(macroexpand-1 '#(zero? (mod 6 %)))
; (fn* [p1__4777#] (zero? (mod 6 p1__4777#)))
or in a more readable code:
(fn* [x]
(zero?
(mod 6 x))
On a single value of a collection, say 3, we can apply the above function:
( (fn* [x]
(zero?
(mod 6 x)))
3)
; true
And then back to the # version of our code, the input parameter of a function is implicitly %, so:
(
#(zero? (mod 6 %))
3)
; true
And finally, back to your original function, you see why # needs to be the function defining the predicate for the filter function:
(filter
#(zero? (mod 6 %))
(range 1 (inc 6)))
; (1 2 3 6)
I am a newbie to clojure (and functional programming for that matter) and I was trying to do some basic problems. I was trying to find the nth element in a sequence without recursion.
so something like
(my-nth '(1 2 3 4) 2) => 3
I had a hard time looping through the list and returning when i found the nth element. I tried a bunch of different ways and the code that I ended up with is
(defn sdsu-nth
[input-list n]
(loop [cnt n tmp-list input-list]
(if (zero? cnt)
(first tmp-list)
(recur (dec cnt) (pop tmp-list)))))
This gives me an exception which says "cant pop from empty list"
I dont need code, but if someone could point me in the right direction it would really help!
You are using the function pop, which has different behavior for different data structures.
user> (pop '(0 1 2 3 4))
(1 2 3 4)
user> (pop [0 1 2 3 4])
[0 1 2 3]
user> (pop (map identity '(0 1 2 3 4)))
ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack clojure.lang.RT.pop (RT.java:640)
Furthermore, you are mixing calls to pop with calls to first. If iterating, use peek/pop or first/rest as pairs, mixing the two can lead to unexpected results. first / rest are the lowest common denominator, if you want to generalize over various sequential types, use those, and they will coerce the sequence to work if they can.
user> (first "hello")
\h
user> (first #{0 1 2 3 4})
0
user> (first {:a 0 :b 1 :c 2})
[:c 2]
With your function, replacing pop with rest, we get the expected results:
user> (defn sdsu-nth
[input-list n]
(loop [cnt n tmp-list input-list]
(if (zero? cnt)
(first tmp-list)
(recur (dec cnt) (rest tmp-list)))))
#'user/sdsu-nth
user> (sdsu-nth (map identity '(0 1 2 3 4)) 2)
2
user> (sdsu-nth [0 1 2 3 4] 2)
2
user> (sdsu-nth '(0 1 2 3 4) 2)
2
user> (sdsu-nth "01234" 2)
\2
given a list as list_nums, take up to n + 1 then from that return the last element which is nth.
(fn [list_nums n] (last (take (inc n) list_nums)))
and alternatively:
#(last (take (inc %2) %1))
proof:
(= (#(last (take (inc %2) %1)) '(4 5 6 7) 2) 6) ;; => true
What you would really want to do is use the built-in nth function as it does exactly what you're asking:
http://clojuredocs.org/clojure_core/clojure.core/nth
However, since you're learning this is still a good exercise. Your code actually works for me. Make sure you're giving it a list and not a vector -- pop does something different with vectors (it returns the vector without the last item rather than the first -- see here).
Your code works fine for lists if supplied index is not equal or greater then length of sequence (you've implemented zero indexed nth). You get this error when tmp-list gets empty before your cnt gets to the zero.
It does not work so well with vectors:
user> (sdsu-nth [1 2 3 4] 2)
;; => 1
user> (sdsu-nth [10 2 3 4] 2)
;; => 10
it seems to return 0 element for every supplied index. As noisesmith noticed it happens because pop works differently for vectors because of their internal structure. For vectors pop will remove elements form the end, and then first returns first value of any vector.
How to fix: use rest instead of pop, to remove differences in behavior of your function when applied to lists and vectors.
(fn [xs n]
(if (= n 0)
(first xs)
(recur (rest xs) (dec n))))
One more way that I thought of doing this and making it truly non recursive (ie without for/recur) is
(defn sdsu-nth
[input-list n]
(if (zero? (count input-list))
(throw (Exception. "IndexOutOfBoundsException"))
(if (>= n (count input-list))
(throw (Exception. "IndexOutOfBoundsException"))
(if (neg? n)
(throw (Exception. "IndexOutOfBoundsException"))
(last (take (+ n 1) input-list))))))
I have a structure where the first element is a function, and the rest args to the fn. Now each arg could in turn be a vector with similar charectristic.
[+ 1 2 3 [- 4 3] 5 6 [- 9 8 [+ 5 6]] 4 5]
How do I write a recursive fn to calculate the result given any such vector ? Also is there any way to just eval it, as the structure will be a valid clojure form if the vector can be replaced by () ?
user=> (def d '[+ 1 2 3 [- 4 3] 5 6 [- 9 8 [+ 5 6]] 4 5])
#'user/d
user=> (defn to-list [elt]
#_=> (if (vector? elt) (map to-list elt) elt))
user=> (to-list d)
(+ 1 2 3 (- 4 3) 5 6 (- 9 8 (+ 5 6)) 4 5)
user=> (eval *1)
17
It's worth noting that eval will take a pretty significant amount of time here:
;; to-list as in Michiel's answer, v is the example from the question
user=> (time (dotimes [_ 100] (eval (to-list v))))
"Elapsed time: 192.098235 msecs"
A simple custom function can be more than an order of magnitude faster:
user=> (defn calcvec [v]
(if (vector? v)
(apply (resolve (first v))
(map calcvec (next v)))
v))
#'user/calcvec
user=> (calcvec v)
17
user=> (time (dotimes [_ 100] (calcvec v)))
"Elapsed time: 15.87096 msecs"
I tried to benchmark these with Criterium, but quick-bench takes way too long on the eval version, so I ended up killing it. (It does fine with calcvec, though.)
Generally speaking, eval makes the most sense for operations performed rarely (perhaps only once), such as compiling a function from a dynamically constructed piece of code etc. So, if you only need to compute the values of a handful such vectors, the eval approach is fine; otherwise you'll be better off with calcvec or something similar. It goes without saying that the eval version can do much more, for example it will handle special forms and macros.