# Parametric Outer Constructor

Looking at #24909, I’m a little confused by constructor for `PushVector`. Here is simple example:

``````struct Foo{T}
a::Int
end

function Foo{T}() where {T}  # what is this?
return Foo{T}(1)
end
``````

The function on the 4th line is unusual because it has the `Foo{T}`. Is it:

• An inner constructor? It can be called like an inner constructor `Foo{Int}()`, but it is not defined inside the type defintion.
• An outer constructor? I thought outer constructors are ordinary functions, and I don’t think functions can have free parameters (perhaps I am wrong about that?)

I have looked over the documentation for constructors and can’t find a case like this.

1 Like

It’s an outer constructor, since as you’ve correctly noted it’s not defined inside the `struct` body. More precisely, it is the function which is called when you call `Foo{X}()` (with an `X` specified).

For example:

``````julia> struct Foo{T}
a::Int
end

julia> function Foo{T}() where {T}
println("called with {T}")
Foo{T}(1)
end

julia> function Foo()
println("called without {T}")
Foo{Int}(1)
end
Foo

julia> Foo{Int}()
called with {T}
Foo{Int64}(1)

julia> Foo()
called without {T}
Foo{Int64}(1)
``````

The first definition is a method for `Foo{T}`, while the second definition is a method for `Foo`.

1 Like

Interesting, so `Foo{T}` is distinct from `Foo`. Taking this one step further, the following works:

``````struct Foo{T, N}
a::Int
end

function Foo{T}() where {T}

return Foo{T, 1}(1)
end

obj = Foo{Int}()
``````

In general, the outer constructor can specify the leading `M` the static parameters, it appears.

Because this behavior is not documented, I want to make sure this is a) intended and b) will be supported in future versions

1 Like

This is definitely intentional and is used all over the place in Julia itself. For example, see:

It is also alluded to in the docs, in Constructors · The Julia Language :

What’s really going on here is that `Point` , `Point{Float64}` and `Point{Int64}` are all different constructor functions. In fact, `Point{T}` is a distinct constructor function for each type `T` .

but I agree that an example like yours would help clarify that section of the documentation a lot.

3 Likes