Clojure: Implementing the comp function
clojure
Solution
Let's try modifying that solution in 3 stages. Stay with each for a while and see if you get it. Stop if and when you do lest I confuse you more.
First, let's have more descriptive names
(defn my-comp [& fns]
(fn [& args]
(reduce (fn [result-so-far next-fn] (next-fn result-so-far))
(apply (last fns) args) (rest (reverse fns)))))
then factor up some
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)
remaining-fns (rest ordered-fns)]
(reduce
(fn [result-so-far next-fn] (next-fn result-so-far))
first-result
remaining-fns))))
next replace reduce with a loop which does the same
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)]
(loop [result-so-far first-result, remaining-fns (rest ordered-fns)]
(if (empty? remaining-fns)
result-so-far
(let [next-fn (first remaining-fns)]
(recur (next-fn result-so-far), (rest remaining-fns))))))))
Problem
4Clojure Problem 58 is stated as: Write a function which allows you to create function compositions. The parameter list should take a variable number of functions, and create a function applies them from right-to-left. ``` (= [3 2 1] ((__ rest reverse) [1 2 3 4])) (= 5 ((__ (partial + 3) second) [1 2 3 4])) (= true ((__ zero? #(mod % 8) +) 3 5 7 9)) (= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world")) ``` Here `__` should be replaced by the solution. In this problem the function `comp` should not be employed. A solution I found is: ``` (fn [& xs] (fn [& ys] (reduce #(%2 %1) (apply (last xs) ys) (rest (reverse xs))))) ``` It works. But I don't really understand how the `reduce` works here. How does it represent `(apply f_1 (apply f_2 ...(apply f_n-1 (apply f_n args))...)`?