You figured out that I had a typo where I renamed f() to snoop(). If you're 
interested in how Julia deals with types, and you may not be, forget the 
weird function-on-the-right thing, and take a look at code_lowered() and 
code_typed().

Most of the bug you found happens during a call to typeintersect, which 
finds the common subtype of two given types. First look at normal 
operation. The call happens twice, once in the definition of the type 
test{T}, when T is a TypeVar, and once when T is an Int.
julia> T=TypeVar(:T, true)
julia> h()=typeintersect(NTuple{T,Int},(Int,Int))
julia> g()=typeintersect(NTuple{2,Int},(Int,Int))

What you found, we'll call f().
julia> f()=typeintersect(NTuple{Float64,Int},(Int,Int))
Now, for each of these, look at code_lowered() and code_typed(), and you'll 
see that substitution happens at earlier steps when there isn't a TypeVar.

julia> code_lowered(f,())
julia> code_typed(f,())
julia> code_llvm(f, ())

NTuple is a strange beast. It isn't a TypeConstructor, such as you would 
form with "typealias IntDict{V} Dict{Int,V}". It isn't a normal parametric 
type either, because it compares with a tuple, but when it becomes a tuple 
depends on when you ask.

In short, my suggested fix was dead wrong and breaks hoards of unit tests. 
I'm learning a lot, but you get all the blame. :)

- Drew

Reply via email to