Why Clojure functions put lists at tail, rather than at head?

while functions put lists at tail:

(defn calculate* []
   (->> (range 10)
        (filter odd? ,,,)
        (map #(* % %) ,,,)
        (reduce + ,,,)))

assoc just functions put data at first argument,

(defn transform* [person]
   (-> person
      (assoc :hair-color :gray)
      (update :age inc)))

so the question, why not put both of them at first argument? for consistency…

1 Like

This and many other answers on why things are the way they are in Clojure are collected in this gist: https://gist.github.com/reborg/dc8b0c96c397a56668905e2767fd697f#what-is-the-convention-for-arguments-order

1 Like

Sounds reasonable as a tradition…

https://docs.racket-lang.org/guide/Lists__Iteration__and_Recursion.html#(part._.Predefined_.List_.Loops)

See also explanation in https://clojure.org/guides/threading_macros

See also the FAQ on clojure.org itself: https://clojure.org/guides/faq#arg_order

There are lots of good explanations on that page for all sorts of things that people ask about when learning Clojure.

so it quoted Rich’s original comment… https://groups.google.com/g/clojure/c/iyyNyWs53dc/m/Q_8BtjRthqgJ

it appear to me that it’s more by convention than being a real benefit of pushing sequence argument at last.

It’s just a convention really. It’s kind of useful for knowing what functions are sequence functions and will call seq on your collection, returning a seq. But even then, there’s some things that don’t follow the convention, so it’s hit or miss I feel.

Where as normally thing that take the coll first return a coll of the same type.

1 Like