user619051
user619051

Reputation: 87

Parametric composite type inner constructors in Julia: Why is `where {T}` necessary?

Why does this raise LoadError: UndefVarError: T not defined:

struct Point{T}
    x::T
    y::T
    Point{T}(x,y) = new(x,y)
end

while this works fine:

struct Point{T}
    x::T
    y::T
    Point{T}(x,y) where {T} = new(x,y)
end

?

It seems that once upon a time they were both fine: Inner constructor of parametric type

EDIT: To clarify, I would have expected the fact that we are within the struct Point{T} block to have made it clear what T refers to even in the first case.

Upvotes: 2

Views: 268

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69949

Without where clause T is inherited from the global scope (which is kind of surprising, but this is how it works):

julia> T = String
String

julia> struct Point{T}
           x::T
           y::T
           Point{T}(x,y) = new(x,y)
       end

julia> Point{String}("b","a")
Point{String}("b", "a")

julia> Point{String}(SubString("b",1,1),SubString("a",1,1))
Point{String}("b", "a")

julia> Point{Int}(1, 2)
ERROR: MethodError: no method matching Point{Int64}(::Int64, ::Int64)

julia> Point{String}(1, 2)
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type String

EDIT

The short answer, given the comments on Discourse, is that the reason for this is that T of struct is not known at the moment an inner constructor is called.

Upvotes: 4

Related Questions