On Sun Sep 25 06:38 2011, Vincent wrote:
> I cannot understand why this does'nt work
>   (apply inc [1 2 3 4])  ; apply inc to each vector element   

From the documentation:

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

This means that apply invokes the function once with the collection
expanded to become the arguments to the function.

So, (apply inc [1 2 3 4]) essentially expands to (inc 1 2 3 4).
However, inc only takes one argument at a time.  What you want to do
instead is invoke the function for each item in the vector.  For this,
there is map:

clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
  Returns a lazy sequence consisting of the result of applying f to the
  set of first items of each coll, followed by applying f to the set
  of second items in each coll, until any one of the colls is
  exhausted.  Any remaining items in other colls are ignored. Function
  f should accept number-of-colls arguments.

Using map, (map inc [1 2 3 4]) essentially becomes: '((inc 1) (inc 2)
(inc 3) (inc 4)), except that it is lazy, meaning that none of the
increments are actually invoked until you actually try to use them.  If
you really want a vector, you can use apply for that:

user=> (apply vector (map inc [1 2 3 4]))
[2 3 4 5]

This apply/map combination is common in Clojure and other functional
languagues.


> while this works
>  (apply println [1 2 3 4]) ;; takes each element and prints it

This works because takes a variable number of arguments.  You can
compare how map and apply differ when using them with println:

user=> (apply println [1 2 3 4]) ; one invocation with all arguments
1 2 3 4
nil
user=> (map println [1 2 3 4]) ; an invocation for each argument
(1
2
3
4
nil nil nil nil)

> why inc can't take each element and incr it giving the result  ... 2 3 4 5

I hope my explanation helps.

Sincerely,

Daniel Solano Gómez

Attachment: signature.asc
Description: Digital signature

Reply via email to