Difference between apply and reduce?

795 views
Skip to first unread message

slix

unread,
Jul 14, 2008, 12:47:52 PM7/14/08
to Clojure
What is the difference between apply and reduce? I am yet to find a
scenario where I can't just them interchangeably.

Graham Fawcett

unread,
Jul 14, 2008, 1:40:39 PM7/14/08
to clo...@googlegroups.com
On Mon, Jul 14, 2008 at 12:47 PM, slix <notnor...@yahoo.se> wrote:

What is the difference between apply and reduce? I am yet to find a
scenario where I can't just them interchangeably.

For certain functions, such as addition, they are the same, but that is because the addition function (+) itself 'reduces' its arguments. In fact the definition of + in Clojure is this:

(defn +
  "Returns the sum of nums. (+) returns 0."
  {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y)))
   :inline-arities #{2}}
  ([] 0)
  ([x] (cast Number x))
  ([x y] (. clojure.lang.Numbers (add x y)))
  ([x y & more]
   (reduce + (+ x y) more)))

Note the reduction in the last case, when more than two arguments are provided.

Reduce is a way of folding a sequence into a single value. (That value itself may be a sequence, but it's still a single value.) If I have a function foo, and a sequence [1 2 3 4], then

(reduce foo [1 2 3 4])
is equivalent to
(foo (foo (foo 1 2) 3) 4)

Apply simply takes a function and a list of arguments, and applies the function to the arguments, e.g.

(apply foo [1 2 3 4])
is equivalent to
(foo 1 2 3 4)

But if foo only takes two arguments, then you'll get an error here.

Does that help?

Best,
Graham


Allen Rohner

unread,
Jul 14, 2008, 1:44:39 PM7/14/08
to Clojure
On Jul 14, 11:47 am, slix <notnorweg...@yahoo.se> wrote:
> What is the difference between apply and reduce? I am yet to find a
> scenario where I can't just them interchangeably.

quoting (doc apply):
"clojure/apply
([f args* argseq])
Applies fn f to the argument list formed by prepending args to
argseq."

(doc reduce):
"clojure/reduce
([f coll] [f val coll])
f should be a function of 2 arguments. If val is not supplied,
returns the result of applying f to the first 2 items in coll, then
applying f to that result and the 3rd item, etc. If coll contains no
items, f must accept no arguments as well, and reduce returns the
result of calling f with no arguments. If coll has only 1 item, it
is returned and f is not called. If val is supplied, returns the
result of applying f to val and the first item in coll, then
applying f to that result and the 2nd item, etc. If coll contains no
items, returns val and f is not called."

Apply unconditionally calls f *once*, accepting any number of
arguments. Reduce takes a function of two arguments and f is called
n-1 times, where n is the number of arguments in your list.

If you have zero or two arguments in your collection, you could use
them interchangably, though it's not a good idea for readability
concerns.

HTH

Allen
Reply all
Reply to author
Forward
0 new messages