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

Convert dispatch depends on the method order? #12939

Closed
maximsch2 opened this issue Sep 4, 2015 · 4 comments
Closed

Convert dispatch depends on the method order? #12939

maximsch2 opened this issue Sep 4, 2015 · 4 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@maximsch2
Copy link
Contributor

Using a sample code:

abstract Abs
type Foo <: Abs
end


type Bar
  val::Int64
end

type Baz
  val::Int64
end


import Base.convert


bar{T <: Abs}(x::T) = 2
bar(x) = 1

baz(x) = 1
baz{T <: Abs}(x::T) = 2


convert{T <: Abs}(::Type{Bar}, x::T) = Bar(2)
convert(::Type{Bar}, x) = Bar(1)


convert(::Type{Baz}, x) = Baz(1)
convert{T <: Abs}(::Type{Baz}, x::T) = Baz(2)


@show convert(Bar, Foo())
@show convert(Baz, Foo())

@show bar(Foo())
@show baz(Foo())

I get this on julia 0.3.11:

convert(Bar,Foo()) => Bar(2)
convert(Baz,Foo()) => Baz(2)
bar(Foo()) => 2
baz(Foo()) => 2

and this on latest 0.4:

convert(Bar,Foo()) = Bar(1)
convert(Baz,Foo()) = Baz(2)
bar(Foo()) = 2
baz(Foo()) = 2

Is this supposed to happen? Note that the only difference between Bar and Baz is in the method definition order and it only happens with convert

@yuyichao yuyichao added the types and dispatch Types, subtyping and method dispatch label Sep 4, 2015
@Keno Keno added this to the 0.4.x milestone Sep 9, 2015
@vtjnash
Copy link
Member

vtjnash commented Sep 9, 2015

reduction:

julia> begin
       abstract Abs
       type Foo <: Abs; end
       type Bar; val::Int64; end
       type Baz; val::Int64; end
       fb{T}(::Type{T}, x::T) = T(3) # this definition is critical for causing 
       fb{T <: Abs}(::Type{Bar}, x::T) = Bar(2) # this method to sort incorrectly
       fb(::Type{Bar}, x) = Bar(1) # the rest don't matter for this example
       fb(::Type{Baz}, x) = Baz(1) # this method helps
       fb{T <: Abs}(::Type{Baz}, x::T) = Baz(2) # this method to end up in the place expected by the author
       end
fb (generic function with 5 methods)

julia> methods(fb)
# 5 methods for generic function "fb":
fb(::Type{Bar}, x) at none:4
fb{T<:Abs}(::Type{Baz}, x::T<:Abs) at none:8
fb(::Type{Baz}, x) at none:7
fb{T}(::Type{T}, x::T) at none:2
fb{T<:Abs}(::Type{Bar}, x::T<:Abs) at none:3

julia> fb(Baz,Foo())
Baz(2)

julia> fb(Bar,Foo())
Bar(1)

@vtjnash
Copy link
Member

vtjnash commented Apr 21, 2016

i assume this'll be fixed by #8974

@vtjnash vtjnash removed this from the 0.4.x milestone Apr 21, 2016
@JeffBezanson
Copy link
Member

Specificity issue, not fixed yet.

@JeffBezanson
Copy link
Member

This is fixed now. Will add a test.

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