Skip to content

Any reason why size(x), axes(x, d), and ndims(x) are not defined for tuples? #49019

@Socob

Description

@Socob
julia> versioninfo()
Julia Version 1.8.5
Commit 17cfb8e65ea (2023-01-08 06:45 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 16 × AMD Ryzen 7 4800H with Radeon Graphics
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, znver2)
  Threads: 1 on 16 virtual cores

julia> t = (1, 2, 3)
(1, 2, 3)

julia> size(t, 1)
3

julia> axes(t)
(Base.OneTo(3),)

julia> axes(t, 1)
ERROR: MethodError: no method matching axes(::Tuple{Int64, Int64, Int64}, ::Int64)
Closest candidates are:
  axes(::Tuple) at tuple.jl:28
  axes(::Base.Broadcast.Broadcasted{<:Any, <:Tuple{Vararg{T, N}} where T}, ::Integer) where N at broadcast.jl:227
  axes(::Number, ::Integer) at number.jl:83
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

julia> size(t)
ERROR: MethodError: no method matching size(::Tuple{Int64, Int64, Int64})
Closest candidates are:
  size(::Tuple, ::Integer) at tuple.jl:27
  size(::Union{LinearAlgebra.Adjoint{T, var"#s886"}, LinearAlgebra.Transpose{T, var"#s886"}} where {T, var"#s886"<:(AbstractVector)}) at /opt/julia-1.8.5/share/julia/stdlib/v1.8/LinearAlgebra/src/adjtrans.jl:173
  size(::Union{LinearAlgebra.Adjoint{T, var"#s886"}, LinearAlgebra.Transpose{T, var"#s886"}} where {T, var"#s886"<:(AbstractMatrix)}) at /opt/julia-1.8.5/share/julia/stdlib/v1.8/LinearAlgebra/src/adjtrans.jl:174
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1

julia> ndims(t)
ERROR: MethodError: no method matching ndims(::Tuple{Int64, Int64, Int64})
Closest candidates are:
  ndims(::Base.Iterators.ProductIterator) at iterators.jl:1015
  ndims(::CartesianIndices) at multidimensional.jl:380
  ndims(::AbstractArray{T, N}) where {T, N} at abstractarray.jl:239
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

Seems a bit inconsistent and strange given that size(t, d) and axes(t) are implemented, and it’d be trivial to implement. Sample implementation:

size(@nospecialize t::Tuple) = (length(t),)
axes(@nospecialize(t::Tuple), d::Integer) = (d == 1) ? OneTo(length(t)) : throw(ArgumentError("invalid tuple dimension $d"))
ndims(@nospecialize ::Tuple) = 1

I also might have expected there to be fallbacks for size(x, d) and axes(x, d) relying on size(x) and axes(x) (or the other way around).

Metadata

Metadata

Assignees

No one assigned

    Labels

    collectionsData structures holding multiple items, e.g. sets

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions