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

map doesn't like most UnitRanges{<:Unsigned} #7709

Closed
jiahao opened this issue Jul 23, 2014 · 3 comments · Fixed by #8043
Closed

map doesn't like most UnitRanges{<:Unsigned} #7709

jiahao opened this issue Jul 23, 2014 · 3 comments · Fixed by #8043

Comments

@jiahao
Copy link
Member

jiahao commented Jul 23, 2014

julia> map(identity, 0x01:0x05)
ERROR: `similar` has no method matching similar(::UnitRange{Uint8}, ::Type{Uint8}, ::(Uint64,))
 in similar at abstractarray.jl:116
 in map at abstractarray.jl:1325

julia> map(identity, 0x0001:0x0005)
ERROR: `similar` has no method matching similar(::UnitRange{Uint16}, ::Type{Uint16}, ::(Uint64,))
 in similar at abstractarray.jl:116
 in map at abstractarray.jl:1325

julia> map(identity, 0x00000001:0x000005) #Uint32 seems to be the only one that works
5-element Array{Uint32,1}:
 0x00000001
 0x00000002
 0x00000003
 0x00000004
 0x00000005

julia> map(identity, uint64(1):uint64(5))
ERROR: `similar` has no method matching similar(::UnitRange{Uint64}, ::Type{Uint64}, ::(Uint64,))
 in similar at abstractarray.jl:116
 in map at abstractarray.jl:1325

julia> map(identity, uint128(1):uint128(5))
ERROR: `similar` has no method matching similar(::UnitRange{Uint128}, ::Type{Uint128}, ::(Uint128,))
 in similar at abstractarray.jl:116
 in map at abstractarray.jl:1325

julia> map(identity, [uint128(1):uint128(5)])
5-element Array{Uint128,1}:
 0x00000000000000000000000000000001
 0x00000000000000000000000000000002
 0x00000000000000000000000000000003
 0x00000000000000000000000000000004
 0x00000000000000000000000000000005
@simonster
Copy link
Member

length of these ranges is not an Int, but a lot of methods seem to expect that. Ironically the first line of range.jl defines typealias Dims (Int...).

@quinnj
Copy link
Member

quinnj commented Aug 18, 2014

If I add

similar(r::Range, T::Type)             = Array(T, size(r)...)

to ranges.jl, it fixes all the cases above, but a few issues.

  • We probably don't want splatting because of the performance hit (because of extra allocation?)
  • There's an ambiguity warning that I think is unfounded, I see the below when building
abstractarray.jl
Warning: New definition
    similar could not show value of type Tuple at abstractarray.jl:117
is ambiguous with:
    similar could not show value of type Tuple at range.jl:167.
To fix, define
    similar could not show value of type Tuple
before the new definition.

I'm guessing the line number is off by one and it's actually ambiguous with

similar   (a::AbstractArray, T)               = similar(a, T, size(a))

But I don't see how they're ambiguous, since Range is strictly more specific than AbstractArray.

The reason this fix works is because it hooks into

Array(T::Type, d::Integer...) = Array(T, convert((Int...), d))

the above core constructor for Arrays rather than dispatching to

Array{T,N}(::Type{T}, d::NTuple{N,Int}) =
    ccall(:jl_new_array, Array{T,N}, (Any,Any), Array{T,N}, d)

which is what all the other similar methods call into (as far as I can tell).

Anyway, sorry to be long-winded, but I'm running into this with a dates test failure for 32-bit, hence my interest 😄

@JeffBezanson
Copy link
Sponsor Member

Nope, the line number is correct. We can get more info from the prompt:

julia> s(r::Range, T::Type)             = Array(T, size(r)...)
s (generic function with 1 method)

julia> s{T}(a::AbstractArray{T}, dims::Dims)   = similar(a, T, dims)
Warning: New definition 
    s(AbstractArray{T,N},(Int64...,)) at none:1
is ambiguous with: 
    s(Range{T},Type{T<:Top}) at none:1.
To fix, define 
    s(Range{T},())
before the new definition.

They overlap at () in the second argument. I know, it sucks.

Maybe we could instead add

similar(r::Range, T::Type, dims::(Integer...)) = Array(T, dims...)

?

quinnj added a commit that referenced this issue Aug 18, 2014
…Integer...) argument. This allows similar to work on ranges where the return type on size() doesn't necessarily equal Dims::(Int...). Fixes #7709.
quinnj added a commit that referenced this issue Aug 26, 2014
…Integer...) argument. This allows similar to work on ranges where the return type on size() doesn't necessarily equal Dims::(Int...). Fixes #7709.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants