Hello Julianistas, 

I'm running into what seems to be a strange inconsistency in the way the 
compiler is treating type parameters.

Consider the following code:

type Bar{T}
    x::T
end

type Foo{T}
    y::Array{Bar{T}}
end

A = [Bar(1), Bar(2), Bar(3)]
B = [Bar(1), Bar("A"), Bar({1,2,3})]

There are two ways one might interpret how T is scoped in Foo{T}. I coded 
this test to investigate which way Julia interprets it, but the problem is 
that it seems to be interpreting it in two different ways at two separate 
points. 

The first way to interpret it: T is the type parameter of EVERY Bar in an 
Array, and is explicitly consistent across Bars, i.e. every Bar in the 
array is of type Bar{T2} where T2 equals the same T as in Foo{T}.

The second way to interpret it: T refers to the type parameter of each 
individual Bar in the Array, and is not explicitly consistent across Bars. 
Thus, if the individual Bars have different type parameters, the overall 
type of the array would be Array{Bar{T},1}.

To test which interpretation Julia uses, I use the arrays A and B above. 
Check out the output when I try to construct different instances of Foo 
with each:

julia> Foo(A)
Foo{Int64}([Bar{Int64}(1),Bar{Int64}(2)])

julia> Foo(B)
ERROR: no method Foo{T}(Array{Bar{T},1})

What's happening here? It seems like the compiler is constraining the 
constructor to the first interpretation, but treats the actual type of the 
object B as it would using the second interpretation. Explicitly:

julia> typeof(A)
Array{Bar{Int64},1}

julia> typeof(B)
Array{Bar{T},1}

How can this be the case? I have also tried creating an explicit outer 
constructor, but got the same error.

Thanks for any insights, 
Jarrett

Reply via email to