Here's my take:

We want to define a function my-comp. It takes n functions and return
their composition.
We want to return a function of any number of arguments, so let's
start by working with a given
set of argument args, and returning the value of the composition
applied to those arguments.

- If I compose only one function, you get the value of the function itself:
  (value-my-comp f)  = (apply f args)

- By definition of composition:
 (value-my-comp f1 f2 .... fn)  = (f1 (value-my-comp f2 .... fn))
(Take all the arguments, apply it to the composition of function f2
.... fn, and then apply the result to f1).

Then you remove the dots:

(value-my-comp f1 & f2-fn) =  (f1  (apply value-my-comp f2-fn))

Then you can just put them all together:


(fn [& fs] ;; we take a bunch of functions in
 (fn [ & args ]  ;; we take the arguments of the resulting function in.
   (letfn [(value-my-comp ;; the value of the result in term of the
functions is:
               ([f] (apply f args))   ;; only one function
               ([f1 & f2-fn] (f1 (apply value-my-comp f2-fn))))]  ;;
more than one function
      (apply value-my-comp fs))))  ;; we compute the value of the
actual function we got.

If you don't like (apply value-my-comp f2-fn), you can make
value-my-comp actually takes a sequence
of functions:

(fn [& fs] ;; take the functions
 (fn [ & args ]  ;; the arguments of the resulting functions
   (letfn [(value-my-comp
            [[f1 & f2-fn]]  ;; a list of functions
              (if (empty? f2-fn)  ;; only one function?
                  (apply f1 args)  ;; then we apply the args to it
                  (f1 (value-my-comp f2-fn))))] ;; else we compose
      (value-my-comp fs))))
This one is another way of writing the one you posted.
(Using a let instead of applying it directly, and not using a
non-varying argument a.)

If you want to see how this function can be written to be very
performant look at
comp source code, it is very interesting.

Best,

Nicolas.

-- 
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

Reply via email to