Reputation:
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
Upvotes: 1
Views: 189
Reputation:
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))
))
Upvotes: 0
Reputation: 17773
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.
Upvotes: 0
Reputation: 33637
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])))
Upvotes: 0
Reputation: 33019
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)])
Upvotes: 3