Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

valtype should fallback to eltype #58081

Open
MilesCranmer opened this issue Apr 11, 2025 · 4 comments
Open

valtype should fallback to eltype #58081

MilesCranmer opened this issue Apr 11, 2025 · 4 comments
Labels
collections Data structures holding multiple items, e.g. sets design Design of APIs or of the language itself iteration Involves iteration or the iteration protocol

Comments

@MilesCranmer
Copy link
Member

MilesCranmer commented Apr 11, 2025

I want to use valtype and keytype as a generic way of getting the value type and index type for a collection—and have the operation be compatible with dict-like collections. It seems some parts of this interface are missing so it would be nice to add fallbacks.

The valtype docstring says:

  • For Array
    • "Return the value type of an array. This is identical to eltype and is provided mainly for compatibility with the dictionary interface."
  • For Dict
    • "Get the value type of a dictionary type. Behaves similarly to eltype."

Based on this I would have guessed that valtype would fallback to eltype so that it can be compatible with any collection. Right now you run into things like

julia> eltype(Set{Float64})
Float64

julia> valtype(Set{Float64})
ERROR: MethodError: no method matching valtype(::Type{Set{Float64}})

which hurts the general use of this function.

@DilumAluthge
Copy link
Member

Hmmm. Technically, aren’t Sets implemented as Dicts under the hood, where the value is always nothing? So technically the valtype(::Set) would always be Nothing, which probably isn’t too useful.

Seems to me it might make more sense to leave valtype(::Set) undefined (current behavior)? But perhaps we can have a trait e.g. HasValtype(), and you can use that to decide whether to call valtype() versus eltype()?

@nsajko nsajko added design Design of APIs or of the language itself collections Data structures holding multiple items, e.g. sets iteration Involves iteration or the iteration protocol labels Apr 12, 2025
@nsajko
Copy link
Contributor

nsajko commented Apr 12, 2025

Set isn't indexable, thus it doesn't have keys or keytype, thus it doesn't have values or valtype either.

@nsajko
Copy link
Contributor

nsajko commented Apr 12, 2025

Oh, wait. The suggestion in the OP is consistent with the fact that values has an ::Any fallback:

julia/base/essentials.jl

Lines 1111 to 1133 in bd193e4

"""
values(iterator)
For an iterator or collection that has keys and values, return an iterator
over the values.
This function simply returns its argument by default, since the elements
of a general iterator are normally considered its "values".
# Examples
```jldoctest; filter = r"^\\s+\\d\$"m
julia> d = Dict("a"=>1, "b"=>2);
julia> values(d)
ValueIterator for a Dict{String, Int64} with 2 entries. Values:
2
1
julia> values([2])
1-element Vector{Int64}:
2
```
"""
values(itr) = itr

The doc string even says:

This function simply returns its argument by default, since the elements of a general iterator are normally considered its "values".

@MilesCranmer
Copy link
Member Author

MilesCranmer commented Apr 12, 2025

Nice find! That’s probably the best argument for this

I think Set wouldn’t have a keytype, but it can have a valtype, which as you point out, would nicely match the values fallback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
collections Data structures holding multiple items, e.g. sets design Design of APIs or of the language itself iteration Involves iteration or the iteration protocol
Projects
None yet
Development

No branches or pull requests

3 participants