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

Subtyping is not reflexive and not transitive with triangular rule #24166

Closed
julbinb opened this issue Oct 16, 2017 · 9 comments
Closed

Subtyping is not reflexive and not transitive with triangular rule #24166

julbinb opened this issue Oct 16, 2017 · 9 comments
Assignees
Labels
domain:types and dispatch Types, subtyping and method dispatch

Comments

@julbinb
Copy link

julbinb commented Oct 16, 2017

In julia 0.6.0 subtyping is not reflexive for some examples.

julia> (Tuple{T, T} where Int<:T<:Int) <: (Tuple{T, T} where Int<:T<:Int)
false

julia> (Tuple{T, T} where T>:Int) <: (Tuple{T, T} where T>:Int)
false

It seems to me that there is a problem with lower bounds in triangular dispatched cases, because these examples work fine:

julia> (Tuple{T, T} where T>:Number) <: (Tuple{T, T} where T>:Number)
true

julia> (Tuple{T, T} where T<:Int) <: (Tuple{T, T} where T<:Int)
true

Also, transitivity is broken:

julia> T1 = Tuple{Number, Number, Ref{Number}}
Tuple{Number,Number,Ref{Number}}

julia> T2 = Tuple{T, T, Ref{T}} where T
Tuple{T,T,Ref{T}} where T

julia> T3 = Tuple{S, S, Ref{Q} where Q} where S
Tuple{S,S,Ref{Q} where Q} where S

julia> T1 <: T2
true

julia> T2 <: T3
true

julia> T1 <: T3
false

Although, to my understanding, T1 <: T2 == true and T1 <: T3 == false are correct, but T2 <: T3 == true is not. So it's not really transitivity, but rather some problem with T2 on the left.

Finally, this looks weird:

julia> (Tuple{T, T} where Number<:T<:Number) <: Tuple{Number, Number}
true

julia> Tuple{Number, Number} <: (Tuple{T, T} where Number<:T<:Number)
true

julia> Vector{Tuple{T, T} where Number<:T<:Number} <: Vector{Tuple{Number, Number}}
false

I don't see why vectors should not be in subtype relation.

Here is the version info:

Julia Version 0.6.0
Commit 903644385b (2017-06-19 13:05 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)

@JeffBezanson

@martinholters
Copy link
Member

julia> Vector{Tuple{T, T} where Number<:T<:Number} <: Vector{Tuple{Number, Number}}
true

on master, so at least that has been fixed.

@JeffBezanson JeffBezanson added the domain:types and dispatch Types, subtyping and method dispatch label Oct 16, 2017
@JeffBezanson
Copy link
Sponsor Member

Thanks for these examples. In fact there was a TODO in the code asking for them. The diagonal rule has been tricky to get right.

@JeffBezanson JeffBezanson self-assigned this Oct 16, 2017
JeffBezanson added a commit that referenced this issue Oct 16, 2017
also put a band-aid on reflexivity of diagonal vars
@julbinb
Copy link
Author

julbinb commented Oct 17, 2017

@JeffBezanson Thanks for the reply and the fix!

Related to this topic: should this example be true or false?

julia> (Tuple{T, T} where T>:Int) <: Tuple{T, T} where T<:Number
false

I would expect true, as there is only Tuple{Int,Int} on the left (for there is only one concrete type >: Int).

@martinholters
Copy link
Member

I had a radical idea the other day: Make Tuples invariant in subtyping. Something like Tuple{Number,Any} would need to become Tuple{<:Number, <:Any}; Tuple{T,T} where T would automatically only match "diagonally" (but T would no longer have to be a leaf type). Up to here, I think this could simplify subtyping by removing lots of special cases. But Vararg would be tricky: Tuple{Vararg{Any}} would implicitly introduce an unknown number of TypeVars (being equivalent to Tuple{T1, T2, ...} where {T1, T2, ...}, which might add complications that could outweigh any benefits.

I guess such a radical change is off the table for 1.0 anyways, but has it been seriously considered in the past? If so, what were the conclusions?

JeffBezanson added a commit that referenced this issue Oct 17, 2017
also put a band-aid on reflexivity of diagonal vars
JeffBezanson added a commit that referenced this issue Oct 17, 2017
also put a band-aid on reflexivity of diagonal vars
@julbinb
Copy link
Author

julbinb commented Oct 18, 2017

@JeffBezanson This doesn't seem right:

julia> Ref{Tuple{T, T} where T} <: Ref{Tuple{S, S}} where S
true

As there doesn't exist single S such that Tuple{T,T} where T == Tuple{S,S}.

But this is fine as is:

julia> Ref{Tuple{T} where T} <: Ref{Tuple{S}} where S
true

In this case we can chose S == Any and

julia> (Tuple{T} where T) == Tuple{Any}
true

@vtjnash
Copy link
Sponsor Member

vtjnash commented Oct 18, 2017

If I remember correctly, the first should be OK, since Ref{Tuple{T, T} where T} should type-equal Ref{Tuple{Any, Any}} (currently seems like subtyping disagrees though).

@julbinb
Copy link
Author

julbinb commented Oct 18, 2017

But Tuple{T,T} where T is a diagonal type, so T cannot be instantiated with Any.

ulysses4ever pushed a commit to ulysses4ever/julia that referenced this issue Oct 20, 2017
also put a band-aid on reflexivity of diagonal vars
@andyferris
Copy link
Member

I too have wondered as @martinholters about exploring invariant tuples (for v2.0 I suppose).

JeffBezanson added a commit that referenced this issue Apr 25, 2019
JeffBezanson added a commit that referenced this issue Apr 25, 2019
JeffBezanson added a commit that referenced this issue Apr 25, 2019
JeffBezanson added a commit that referenced this issue Apr 26, 2019
JeffBezanson added a commit that referenced this issue Apr 26, 2019
JeffBezanson added a commit that referenced this issue May 9, 2019
JeffBezanson added a commit that referenced this issue May 29, 2019
JeffBezanson added a commit that referenced this issue Jun 24, 2019
JeffBezanson added a commit that referenced this issue Dec 11, 2019
@vtjnash vtjnash closed this as completed Mar 29, 2022
@vtjnash
Copy link
Sponsor Member

vtjnash commented Mar 29, 2022

Seems corrected now

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

Successfully merging a pull request may close this issue.

5 participants