On Sat, Aug 25, 2012 at 6:47 PM, John Holland <jbholl...@gmail.com> wrote:
> This problem is really confusing me. I found a solution online, but I > can't understand the solution. Can anyone explain to me why this > works? > > The problem 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])) > > > The examples would accept the solution replacing the ____. > > The solution I found is: > > (fn [x & xs] > (fn [& args] > ((fn step [[f & fs] a] > (if fs > (f (step fs a)) > (apply f a))) > (cons x xs) args))) > > > This works, and baffles me when I try to understand it. > It's obfuscated by the fact that in 4clojure, the smaller is the code, the higher is your score. Divide & Conquer works fine here to understand what's going on: https://gist.github.com/3468564 : ;; you are starting here (fn [x & xs] (fn [& args] ((fn step [[f & fs] a] (if fs (f (step fs a)) (apply f a))) (cons x xs) args))) ;; name the fn (defn mycomp [x & xs] (fn [& args] ((fn step [[f & fs] a] (if fs (f (step fs a)) (apply f a))) (cons x xs) args))) ;; extract the step function (defn step "Equivalent to (apply (comp f & fs) args)" [[f & fs] args] (if fs (f (step fs args)) (apply f args))) (defn mycomp "Equivalent to (partial step fns)" [& fns] (fn [& args] (step fns args))) ;; rename a few things for clarity (defn comp-then-apply "Equivalent to (apply (comp f & fs) args)" [[f & fs] args] (if fs (f (comp-then-apply fs args)) (apply f args))) (defn mycomp "Equivalent to (partial comp-then-apply fns)" [& fns] (fn [& args] (comp-then-apply fns args))) And use the REPL luke! HTH Denis > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en