Helo, In an effort to learn clojure, I have taken an interest in clojure.core functions that act on sequences. Recently, I noticed some odd behaviour and would like an explaination of the difference between the folling expressions:
What I'm trying to do is this:
user=> (reduce + (take-while (partial > 1000) (iterate inc 1)))
499500
However, when I store (iterate inc 1) with def a get an error:
user=> (def a (iterate inc 1))
#'user/a
user=> (reduce + (take-while (partial > 1000) (a)))
java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
Could someone please explain what the difference between storing iterate inc 1 and using it directly in the expression? I know that a is a lazy sequence but am missing something...
Thank you very much for your time.
You should be doing
(reduce + (take-while (partial > 1000) a))
(a) attempts to call a, but it's not a function.
Related
This question already has an answer here:
Wrong number of args (0) passed to: PersistentVector on loop/recur function
(1 answer)
Closed last year.
I'am new to clojure and i wrote this func:
(def fact (fn [n] (
(apply * (drop 1 (range n))))))
When calling it i get the error:
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') my-stuff.core/fact (form-init3352210926102455316.clj:18)
Why?
You've got an extra parenthesis around apply:
(def fact (fn [n]
(apply * (drop 1 (range n)))))
There's extra pair of parentheses- when you call for example (fact 3), result will be (2) (not list, but call of function) and 2 isn't function, so it throws error.
When you remove these parentheses, like this:
(def fact (fn [n]
(apply * (drop 1 (range n)))))
, call (fact 3) returns 2- but is this result correct? If you want to return factorial for given number, you have to use range correctly:
(defn fact [n]
(->> (range 1 (inc n))
(apply *)))
(->> is thread-last macro)
Example:
(fact 3)
=> 6
Consider a query function q that returns, with a delay, some (let say ten) results.
Delay function:
(defn dlay [x]
(do
(Thread/sleep 1500)
x))
Query function:
(defn q [pg]
(lazy-seq
(let [a [0 1 2 3 4 5 6 7 8 9 ]]
(println "q")
(map #(+ (* pg 10) %) (dlay a)))))
Wanted behaviour:
I would like to produce an infinite lazy sequence such that when I take a value only needed computations are evaluated
Wrong but explicative example:
(drop 29 (take 30 (mapcat q (range))))
If I'm not wrong, it needs to evaluate every sequence because it really doesn't now how long the sequences will be.
How would you obtain the correct behaviour?
My attempt to correct this behaviour:
(defn getq [coll n]
(nth
(nth coll (quot n 10))
(mod n 10)))
(defn results-seq []
(let [a (map q (range))]
(map (partial getq a)
(iterate inc 0)))) ; using iterate instead of range, this way i don't have a chunked sequence
But
(drop 43 (take 44 (results-seq)))
still realizes the "unneeded" q sequences.
Now, I verified that a is lazy, iterate and map should produce lazy sequences, so the problem must be with getq. But I can't understand really how it breaks my laziness...perhaps does nth realize things while walking through a sequence? If this would be true, is there a viable alternative in this case or my solution suffers from bad design?
Hey I'm doing a Project Euler question, and I'm looking to sum up all the numbers under 1000 that are multiplies of 3 or 5.
But being a clojure noob, my code just keeps returning zero.. and I'm not sure why.
(defn sum-of-multiples [max]
(let [result (atom 0)]
(for [i (range max)]
(if (or (= (rem i 3) 0) (= (rem i 5) 0))
(swap! result (+ #result i)))
)
#result))
(sum-of-multiples 1000)
Also the line (swap! result (+ #result i))) bugs me.. In C# I could do result += i, but I'm guessing there must be a better way to this in Clojure?
In Clojure - and at large in functional programming - we avoid assignment as it destroys state history and makes writing concurrent programs a whole lot harder. In fact, Clojure doesn't even support assignment. An atom is a reference type that is thread safe.
Another common trait of functional programming is that we try to solve problems as a series of data transformations. In your case you case some data, a list of numbers from 0 to 1000 exclusive, and you need to obtain the sum of all numbers that match a predicate. This can certainly be done by applying data transformations and completely removing the need for assignment. One such implementation is this:
(->> (range 1000)
(filter #(or (= (rem % 3) 0) (= (rem % 5) 0)))
(reduce +))
Please understand that a function such as the one you wrote isn't considered idiomatic code. Having said that, in the interest of learning, it can be made to work like so:
(defn sum-of-multiples [max]
(let [result (atom 0)]
(doseq [i (range max)]
(if (or (= (rem i 3) 0) (= (rem i 5) 0))
(swap! result #(+ % i)))
)
#result))
(sum-of-multiples 1000)
for returns a lazy sequence but since you're simply interested in the side-effects caused by swap! you need to use doseq to force the sequence. The other problem is that the second argument to swap! is a function, so you don't need to deref result again.
for is a list comprehension that return a lazy sequence, you have to traverse it for your code to work:
(defn sum-of-multiples [max]
(let [result (atom 0)]
(dorun
(for [i (range max)]
(if (or (= (rem i 3) 0) (= (rem i 5) 0))
(swap! result + i))))
#result))
An equivalent, more idiomatic implementation using for:
(defn sum-of-multiples [max]
(reduce +
(for [i (range max)
:when (or (zero? (rem i 3))
(zero? (rem i 5)))]
i)))
The other answers are good examples of what I alluded to in my comment. For the sake of completeness, here's a solution that uses loop/recur, so it may be easier to understand for someone who's still not comfortable with concepts like filter, map or reduce. It also happens to be about 30-40% faster, not that it really matters in this case.
(defn sum-of-multiples [max]
(loop [i 0
sum 0]
(if (> max i)
(recur (inc i)
(if (or (zero? (rem i 3)) (zero? (rem i 5)))
(+ sum i)
sum))
sum)))
http://clojuredocs.org/clojure_core/clojure.core/-%3E
(def step #(-> [(% 1) (+ (% 0) (% 1))]))
(def fib #(map first (iterate step [0 1])))
The code above generates Fib sequence, and I want to rewrite the 2nd line like below:
(def fib #(-> (iterate step [0 1]) (map first)))
or
(def fib #(-> [0 1] (iterate step) (map first)))
However, the both code failes when
(println
(take 10 (fib))
)
with an error
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$first
Is it impossible to rewrite like these or any proper way?
Thanks.
You want the ->> thread-last macro.
Is it possible to code using #, %1, %2 for the below?
(defn fib-step [[a b]]
[b (+ a b)])
(defn fib-seq []
(map first (iterate fib-step [0 1])))
user> (take 20 (fib-seq))
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
In short, I'd like to know how to write
vector -> vector function using # and % syntax sugar.
Thanks
You can easily produce a vector using the #() reader form with the -> threading macro. For example, the following two functions are equivalent:
(fn [a b] [b a])
#(-> [%2 %])
However, if you need to do destructuring, as in your case, you're best off just sticking with one of the fn forms with an explicit parameter list. The best you'd get with #() is something like this:
#(-> [(% 1) (+ (% 0) (% 1))])
or
#(-> [(% 1) (apply + %)])
Using the higher-order juxt function is another nice way to create vectors, but unfortunately in this case it doesn't buy you much either:
(def fib-step (juxt second #(apply + %)))
I think out of all the options, using fn is still the best fit because of its easy support for destructuring:
(fn [[a b]] [b (+ a b)])
I would suggest making fib-step take 2 parameters rather than a vector as that would make things more clear that this function need two values whereas a vector as param means it can take any number of values as param (in the form of the vector).
(def fib-step #(-> [%2 (+ %1 %2)]))
(defn fib-seq []
(map first (iterate (partial apply fib-step) [0 1])))
I think using the vector function is clearer than the (-> [...]) "trick":
#(vector (% 1) (apply + %))
Though in this instance, with destructuring, I'd just use a named function or (fn [...] ...) anyway.
Here is the code:
(def step #(-> [(% 1) (+ (% 0) (% 1))]))
(def fib #(map first (iterate step [0 1])))
(println
(take 20 (fib))
)
or
(def step #(-> [(% 1) (+ (% 0) (% 1))]))
(def fib (->> [0 1]
(iterate step)
(map first)))
(println
(->> fib
(take 20))
))