There are three things going on here:
-
The name
T
is just like any other name, likeTT
or evenInt
. When you define a method, the types need to be identified by something — and that thing can be (and almost always is) a global name. Typically it’s a constant global, but it can be non-constant, too. It’ll just define the method based upon the value when the method was defined. -
The syntax
Point{Int}(...) = ...
is defining a constructor forPoint{Int}
. Before thewhere
revolution, this syntax meant something completely different — it was how we introduced local type variables for a method signature. So yes, the meaning here changed (and did so dramatically) and it was very intentional — the disambiguation between defining a method onPoint{Int}()
vs. a method onPoint()
is a huge benefit from thewhere
clause. -
We introduce type parameters for structs in their definition: the syntax
struct Point{T}
is how we introduce a local nameT
that can be used in field definitions and the parameters of supertypes. Now here’s the confusing part — thatT
isn’t available to inner constructors, even though it’s written within the same indented block. In fact it cannot be because when you call an inner constructor thePoint
hasn’t be constructed yet so it doesn’t know what thatT
is! The inner constructor can even change what the parameter is compared to how it was called:julia> struct Point{T} x::T y::T Point{Int}(x,y) = new{Float64}(x,y) end julia> Point{Int}(1,2) Point{Float64}(1.0, 2.0)
Ok, so that case is crazy and of course you wouldn’t want to do that in real code. But in real code you do often want to compute some additional parameter that cannot be derived automatically. And in such cases, you “get into” the inner constructor without knowing what the type parameters of the
struct
are.So, yeah, it’s confusing that the type parameters of a struct aren’t available to inner constructors. But it is simply because they’re not known yet. I suppose it’d be nice if the way we spelled out struct definitions would make that more obvious, but there’s a value to the simplicity of where we put our inner constructors.