Return value of findmin/findmax

I would love if functions like findmin and findmax used a named tuple for their return value, because I can never remember which element of the return value is which (and code like findmax(arr)[2] has high mental load as a result).

11 Likes

Come to think of it, maybe the reason findmin and findmax have such high mental load is because their return value is backwards.

Everywhere else, key-value pairs appear as k=>v and index-value pairs as (i,x) (e.g. as from enumerate), but findmin and findmax return index and value in opposite order.

WhyWhateverGIF

7 Likes

I would argue that this is because the minimum is the main focus of the function, otherwise it might be called findminindex if the index (key) came first?

For me the mental load here is that though it is called findmin is also does findminindex (which computationally of course makes sense).

I don’t quite agree with that; the main focus is finding it: “Where is the minimum?”

You already have minimum to tell you what the minimum is, so I would expect findmin to have a different focus, namely location.

6 Likes

You are actually right, since we have minimum, then one could have also switched the result entries, yes.

I’m visiting Milan, Italy, at the moment. I encountered an elevator that has the following sequence:

[-3 -2 -1 0 'A' 1 2 3 4]

On findmin and findmax, how breaking would it be if it returned a NamedTuple instead or perhaps via an additonal argument?

2 Likes

“Where is the minimum?”

This is best answered by argmin, because it only returns the position.

findmin really tries to answer: “What is the minimum and where is it?”

4 Likes

Or “Where is the minimum and what is it?” :wink:

7 Likes

argmin isn’t really consistent here: sometimes it returns the position, sometimes the element. findmin is consistent and always does the same, and is less error-prone because of that.

julia> A = [5, 1, 3, -10]

# index:
julia> argmin(A)
4
# value:
julia> argmin(abs, A)
1

# (value, index):
julia> findmin(A)
(-10, 4)
# also (value, index):
julia> findmin(abs, A)
(1, 2)
6 Likes

Wow. Didn’t know that. That is pretty unfortunate …

1 Like

Definitely unfortunate. There is an issue to fix this in the hypothetical far-future Julia 2.0

1 Like

see discussion: Unintuitive findmin and findmax · Issue #39203 · JuliaLang/julia · GitHub

2 Likes

Apparently it would break broadcasting, which seems like a good thing imo

I agree; the return values of findmin/findmax look backwards.

Moreover, it seems a missed opportunity to return a Pair, which would make the key => value order semantically clear.

julia> findmin("hello")
('e', 2)

julia> findmin′(iter) = Pair(reverse(findmin(iter))...)
findmin′ (generic function with 1 method)

julia> findmin′("hello")
2 => 'e'

Pairs are just as convenient as tuples for destructuring, etc.

3 Likes

JensenAcklesPointingGIF

3 Likes

I completely agree that changing the order/type of the output would be an improvement. Is it at all in the cards to make such a breaking change for 2.0 though?