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

parameter constraints in subtype declarations can conflict with the supertype #9441

Open
goretkin opened this issue Dec 22, 2014 · 5 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@goretkin
Copy link
Contributor

Suppose we have the following definitions

#type this into session 1
abstract Domain{T<:Number}
immutable Interval{T} <: Domain{T}
    a::T
    b::T
end

For the purposes of this issue I expect the following block of code to work exactly as the above (if you type them each into a different Julia session). Perhaps this is not a justified expectation.

#type this into session 2
immutable Interval{T<:Number} 
    a::T
    b::T
end

In both sessions, this works as expected

julia> Interval{Float64}(3,4)
Interval{Float64}(3.0,4.0)

julia> Interval("he","llo")
ERROR: type: Domain: in T, expected T<:Number, got Type{ASCIIString}

but if you go on to define in each session

Interval(a::Number,b::Number) = Interval(promote(a,b)...)

then session 1 loops on Interval(3,4.) (and any number types) but it works as I expect in session 2.
This is consistent with the following

#session 1 
julia> methods(Interval)
#2 methods for generic function "Interval":
Interval(a::Number,b::Number) at none:1
Interval{T}(a::T,b::T)
#session 2
julia> methods(Interval)
#2 methods for generic function "Interval":
Interval{T<:Number}(a::T<:Number,b::T<:Number)
Interval(a::Number,b::Number) at none:1

The solution seems to be to be redundant

#type this into session 1
abstract Domain{T<:Number}
immutable Interval{T<:Number} <: Domain{T}
    a::T
    b::T
end

Furthermore, I think this should raise some kind of red text

#a new session
abstract Domain{T<:Number}
immutable Interval{T<:String} <: Domain{T}
    a::T
    b::T
end

because it seems like that type is not able to be constructed

julia> Interval("he","llo")
ERROR: type: Domain: in T, expected T<:Number, got Type{ASCIIString}

julia> Interval(3,4)
ERROR: `Interval{T<:String}` has no method matching Interval{T<:String}(::Int64, ::Int64)
@goretkin
Copy link
Contributor Author

I didn't look at these examples carefully, but it seems like all of the parametric abstract subtyping in Base does not rely on my expectation above

goretkin-mbp:julia goretkin$ git grep -P "abstract\s+.+{.+}\s*<:\s*.*{.+}"
base/boot.jl:#abstract DenseArray{T,N} <: AbstractArray{T,N}
base/range.jl:abstract Range{T} <: AbstractArray{T,1}
base/range.jl:abstract OrdinalRange{T,S} <: Range{T}
base/sparse/abstractsparse.jl:abstract AbstractSparseArray{Tv,Ti,N} <: AbstractArray{Tv,N}
examples/lru.jl:abstract LRU{K,V} <: Associative{K,V}
test/core.jl:abstract Qux_{T} <: Sup_{Qux_{Int},T}

@vtjnash
Copy link
Member

vtjnash commented Dec 23, 2014

probably related to #6721

also #8974

@ihnorton ihnorton added the types and dispatch Types, subtyping and method dispatch label Jan 30, 2015
@mauro3
Copy link
Contributor

mauro3 commented Sep 24, 2015

#13297 has a more concise description.

@mauro3
Copy link
Contributor

mauro3 commented Jun 28, 2016

Another oddness caused by this:

abstract AA{T<:Number}
type A{T} <: AA{T} end
@show A<:AA  # --> false
@show subtypes(AA) #  Any[A{T<:Number}] <-- still listed as subtype


abstract BB{T<:Number}
type B{T<:Number} <: BB{T} end
@show B<:BB # --> true
@show subtypes(BB) # Any[A{T<:Number}]

@JeffBezanson
Copy link
Member

#6383 also related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

5 participants