Search code examples
clojure

Clojure "map" function ordering guarantees?


The doc for map says:

user=> (doc map)

clojure.core/map
([f] [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. Returns a transducer when
  no collection is provided.
nil

applying f to the set makes me unsure about whether f is applied to the sequence of n-th elements of every collection passed in to give the n-th element of the result sequence.

In other words:

Is there a guarantee that

(map str [ "1" "2" "3" ] [ "a" "b" "c" ] )

will always return

("1a" "2b" "3c")

and never

("a1" "b2" "3c")

?


Solution

  • Yes, (map str ["1" "2" "3"] ["a" "b" "c"]) will always return ("1a" "2b" "3c").

    From the source code here you can see it calls the function on (first s1) (first s2) and then calls (map f (rest s1) (rest s2)), so it always processes them in order:

    https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2756

    Before it starts it calls seq on each of the collections. For an ordered collection like a vector, the elements in the resulting seq will always have the same order as the original collection. For an unordered set, you cannot expect them in a particular order, but that's not the case you're asking about.