trying to do compose (#58)
(defn compose [& fns]
(fn [a & opts]
(if opts
;println can be removed, just shows my confusion
(reduce (fn [x y] (println(apply y (list x))) (apply y (list x))) (cons a opts) (reverse fns)))
(reduce (fn [x y] (y x)) a (reverse fns))))
((compose rest reverse) 1 2 3 4)
I've killed too much time on this so I'm resorting to asking for help... I've only got about 2-3 days experience so forgive the ugly clojure and the most likely unnecessary if form. I'd like to know what is wrong with this, as opposed to getting a completely different (and I'm sure nicer) answer.
What's confusing me is that the error is indicating I am trying to call a list as a function, but the print statement is showing exactly the results I would expect, using the same code as the function body.
I think you just got your parens in the wrong place. This works:
(defn compose [& fns]
(fn [a & opts]
(if opts
(reduce (fn [x y] (apply y (list x))) (cons a opts) (reverse fns))
(reduce (fn [x y] (y x)) a (reverse fns)))))
It was easy for me to see the problem right away because I use an editor that understands about parens and alignment - I just put your code in IntelliJ/Cursive. Cursive uses structural editing (otherwise known as Paredit).
Also when debugging be aware that println
returns nil. I often use a probe function for this kind of debugging:
(defn probe-on
([x]
(println x)
x)
([x msg]
(println msg x)
x))
, but you can now (or coming, they are still a little new) get editors/debuggers that don't require you to use such debugging techniques. See proto-REPL and Sayid.