Bleh, I've been completely wrong about what currying does. Here's a
correct definition:

(defn curry [f]
  (fn [a]
    (fn [b] (f a b))

So curry basically takes a fn f that normally operates on a pair, and
creates an fn that "partially applies" f to an argument. That function
in turn will complete the computation when it receives the final
value, making a curried fn a kind of two stage partial application.
So:

(def add-n (curry +))     ; note that curry itself doesn't apply
anything

(def add-five (add-n 5))  ; first stage where the curried function
"applies" a first argument

(add-five 4) => 9           ; Blap :)

in general: (((curry f) a) b)  <=>  (f a b)

Note, this is kind of ackward in clojure! Curry is limited because its
purpose is to simplify functions on pairs of value, which is useful in
strict lambda calculus. Luckily we're in clojure. Here, it feels
ackward that we can give curry a function of variable arity just to
have curry turn it into a function on two args, and curry fails for
functions with more than 2 fixed arguments. So lets write a curry that
takes advantage of functions of [& args], like + above:

(defn curry2 [f]
  (fn [& x]
    (fn [& y]
      (apply f (concat x y))

This allows us to give our curried function multiple arguments in each
stage, which, although not motivated for an associative function like
+, feels more 'clojurish':

(def add-n (curry2 +))

(def add-ten (add-n 1 2 3 4))

(add-ten 6 6 6) ; => 28

And lets see if we can take a function curried this way, and
reconstruct the original function:

(defn uncurry [f]
  (fn [& args]
    ((f args)) ))

((uncurry add-n) 1 2 3 4) => 10

In general, (uncurry (curry f)) => f

Neat! A curried function is a higher order function and unlike a
partially applied function, it remains equivalent to the original
function.

I'll admit, this all still seems a bit unmotivated here in clojure.
I'm sure we can break curry2 with functions of fixed arity, and it
doesn't allow us progressively partially apply a function of many
arguments, which could be a useful thing. But I think we can write one
interesting fact:

  partial = (curry apply)

What? Really? Heh, I don't know, I gotta check it out later, back to
work here :)

-max


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