Consider the following code:

(def values [[1 2] [3 4] [5] [6 7] [8]])

(apply max-key count values)

; => [6 7]

Which returns the *last* max entry [6 7]. Why its not the first max entry [1 2]?

Well, truth is "max-key" gives no warranty on which max value will be returned.

Consider the following example in Scala:

println(List(List(0, 1, 2), List(2, 3, 4), List(1), List(1, 2, 3)).maxBy(_.length))

> List(0, 1, 2)

The very same function in Scala returns the *first* max entry (by default).

The code from relase 1.4 file "clojure/core.clj#4419-4426" looks is:

=======================

4419: (defn max-key

4420: "Returns the x for which (k x), a number, is greatest."

4421: {:added "1.0"

4422: :static true}

4423: ([k x] x)

4424: ([k x y] (if (> (k x) (k y)) x y))

4425: ([k x y & more]

4426: (reduce1 #(max-key k %1 %2) (max-key k x y) more)))

=======================

I am unsure what is the motivation in returning the last candidate, but

I suggest two following things:

1. Make "max-key" and "min-key" return the *first* max/min entry if there are several candidates.

This behavior seems more natural/convenient (to me), because in most cases you want to get first "winner".

(e.g. find the first biggest vector in a sequence) and less often you need to get the last entry -- in those cases

you can do "reverse" before feeding a sequence to "max-key", thus it seems having "return first max" behavior more useful.

Line #4424 should have ">=" instead of ">".

2. Make "max-key" and "min-key" make warranty on order, which max/min entry will be returned (either first or last).

Line #4420 should say "Returns the x for which (k x), a number, is greatest. In case of several matches, the first max entry will be returned" or the same doc, but saying "the last max entry will returned".

(def values [[1 2] [3 4] [5] [6 7] [8]])

(apply max-key count values)

; => [6 7]

Which returns the *last* max entry [6 7]. Why its not the first max entry [1 2]?

Well, truth is "max-key" gives no warranty on which max value will be returned.

Consider the following example in Scala:

println(List(List(0, 1, 2), List(2, 3, 4), List(1), List(1, 2, 3)).maxBy(_.length))

> List(0, 1, 2)

The very same function in Scala returns the *first* max entry (by default).

The code from relase 1.4 file "clojure/core.clj#4419-4426" looks is:

=======================

4419: (defn max-key

4420: "Returns the x for which (k x), a number, is greatest."

4421: {:added "1.0"

4422: :static true}

4423: ([k x] x)

4424: ([k x y] (if (> (k x) (k y)) x y))

4425: ([k x y & more]

4426: (reduce1 #(max-key k %1 %2) (max-key k x y) more)))

=======================

I am unsure what is the motivation in returning the last candidate, but

I suggest two following things:

1. Make "max-key" and "min-key" return the *first* max/min entry if there are several candidates.

This behavior seems more natural/convenient (to me), because in most cases you want to get first "winner".

(e.g. find the first biggest vector in a sequence) and less often you need to get the last entry -- in those cases

you can do "reverse" before feeding a sequence to "max-key", thus it seems having "return first max" behavior more useful.

Line #4424 should have ">=" instead of ">".

2. Make "max-key" and "min-key" make warranty on order, which max/min entry will be returned (either first or last).

Line #4420 should say "Returns the x for which (k x), a number, is greatest. In case of several matches, the first max entry will be returned" or the same doc, but saying "the last max entry will returned".