Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: why must parametric types have outer constructors?

Tags:

julia

The following works:

type TypeA
       x :: Array
       y :: Int
       TypeA(x :: Array ) = new(x, 2)
       end

julia> y = TypeA([1,2,3])
TypeA([1,2,3],2)

This does not:

type TypeB{S}
       x :: Array{S}
       y :: Int
       TypeB{S}( x:: Array{S} ) = new(x,2)
       end

julia> y = TypeB([1,2,3])
ERROR: `TypeB{S}` has no method matching TypeB{S}(::Array{Int64,1})

In order to get the second case to work, one has to declare the constructor outside of the type declaration. This is slightly undesirable. My question is why this problem exists from a Julia-design standpoint so I can better reason about the Julia type-system.

Thank you.

like image 476
Mageek Avatar asked Sep 04 '14 16:09

Mageek


1 Answers

This works:

type TypeB{S}
    x::Array{S}
    y::Int
    TypeB(x::Array{S}) = new(x,2)
end
TypeB{Int}([1,2,3])

which I figured out by reading the manual, but I must admit I don't really understand inner constructors that well, especially for parametric types. I think its because you are actually defining a family of types, so the inner constructor is only sensible for each individual type - hence you need to specify the {Int} to say which type you want. You can add an outer constructor to make it easier, i.e.

type TypeB{S}
    x::Array{S}
    y::Int
    TypeB(x::Array{S}) = new(x,2)
end
TypeB{S}(x::Array{S}) = TypeB{S}(x)
TypeB([1,2,3])

I think it'd be good to bring it up on the Julia issues page, because I feel like this outer helper constructor could be provided by default.

EDIT: This Julia issue points out the problems with providing an outer constructor by default.

like image 55
IainDunning Avatar answered Dec 05 '22 09:12

IainDunning