Why does Base.findmin assume that Combinatorics.Permutations has a `keys` method?

With Julia 1.8.0-rc1:

``````julia> using Combinatorics

julia> findmin(collect(permutations(1:3, 1)))  # Works fine.
([1], 1)

julia> findmin(permutations(1:3, 1))  # Fails.
ERROR: MethodError: no method matching keys(::Combinatorics.Permutations{UnitRange{Int64}})
Closest candidates are:
keys(::IndexStyle, ::AbstractArray, ::AbstractArray...) at abstractarray.jl:356
keys(::Base.Generator) at generator.jl:54
keys(::Tuple) at tuple.jl:71
...
Stacktrace:
[1] pairs(collection::Combinatorics.Permutations{UnitRange{Int64}})
@ Base ./abstractdict.jl:172
[2] findmin(f::typeof(identity), domain::Combinatorics.Permutations{UnitRange{Int64}})
@ Base ./reduce.jl:944
[3] _findmin(a::Combinatorics.Permutations{UnitRange{Int64}}, #unused#::Colon)
@ Base ./reduce.jl:970
[4] findmin(itr::Combinatorics.Permutations{UnitRange{Int64}})
@ Base ./reduce.jl:969
[5] top-level scope
@ REPL[3]:1
``````

Can someone explain this?

`keys` is not limited to dictionaries:

``````help?> keys
search: keys keytype KeyError haskey getkey UndefKeywordError WeakKeyDict

keys(a::AbstractArray)

Return an efficient array describing all valid indices for a arranged
in the shape of a itself.

They keys of 1-dimensional arrays (vectors) are integers, whereas all
other N-dimensional arrays use CartesianIndex to describe their
locations. Often the special array types LinearIndices and
CartesianIndices are used to efficiently represent these arrays of
integers and CartesianIndexes, respectively.

Note that the keys of an array might not be the most efficient index
type; for maximum performance use eachindex instead.

ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ

keys(iterator)

For an iterator or collection that has keys and values (e.g. arrays
and dictionaries), return an iterator over the keys.

[...]
``````
1 Like

True. So a better description of whatβs actually happening seems to be that findmin assumes that its argument type has a `keys` method (that is, findmin assumes its argument is either an array or a dictionary).

So, is this a Julia Base bug, a Combinatorics bug, or neither?

To the extent that itβs a bug, itβs a Combinatorics bug.

1 Like