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