On Monday, December 15, 2014 4:50:06 AM UTC+10, Gustavo Goretkin wrote:
>
> (Julia Version 0.3.4-pre+47)
>
> I didn't expect this
>
> julia> f{T}(x::Complex{T},y::T) = println("here")
> f (generic function with 1 method)
>
> julia> f{T}(x::Complex{T},y::Real) = begin println("there");
> f(x,convert(T,y)) end
> f (generic function with 2 methods)
>
> julia> methods(f)
> # 2 methods for generic function "f":
> f{T}(x::Complex{T},y::Real) at none:1
> f{T}(x::Complex{T},y::T) at none:1
>
> julia> f(Complex(1.0),1.0)
>
> The last line causes an infinite recursion because
>
>
> julia> @which f(Complex(1.0),1.0)
> f{T}(x::Complex{T},y::Real) at none:1
>
> I expected f{T}(x::Complex{T},y::T) to be more specific than
> f{T}(x::Complex{T},y::Real).
>
I would have agreed that f{T}(x::Complex{T},y::T) would make T a concrete
type and so to be "more specific" than an abstract type Real. But the
rules for "more specific" are not documented anywhere I could find so its
possible having the type of y depend on the parameter is considered less
specific It would be good if "somebody" who understands this part of the
Julia code could put a simple table and explanation in the docs.
Cheers
Lex
>
> If I remove ::Real, everything works as I expect
>
Yes, Any is definitely less specific than any type.
>
> julia> f{T}(x::Complex{T},y::T) = println("here")
> f (generic function with 1 method)
>
> julia> f{T}(x::Complex{T},y) = begin println("there"); f(x,convert(T,y))
> end
> f (generic function with 2 methods)
>
> julia> methods(f)
> # 2 methods for generic function "f":
> f{T}(x::Complex{T},y::T) at none:1
> f{T}(x::Complex{T},y) at none:1
>
> julia> f(Complex(1.0),1.0)
> here
>
> julia> f(Complex(1.0),1)
> there
> here
>
> I thought it might have been an instance of
> https://github.com/JuliaLang/julia/issues/7221 but defining the methods
> in the opposite order doesn't change the result.
>