# Parametric Outer Constructor

**URL:** <https://discourse.julialang.org/t/parametric-outer-constructor/20874>\
**Category:** General Usage\
**Created:** [February 16, 2019, 8:47pm UTC](https://discourse.julialang.org/t/parametric-outer-constructor/20874 "2019-02-16T20:47:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![JaredCrean2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jaredcrean2/32/3574_2.png) [@JaredCrean2](https://discourse.julialang.org/u/JaredCrean2)\
**Post date:** [February 16, 2019, 8:47pm UTC](https://discourse.julialang.org/t/parametric-outer-constructor/20874/1 "2019-02-16T20:47:07Z")

</div>

Looking at [#24909](https://github.com/JuliaLang/julia/issues/24909#issuecomment-419731925), I’m a little confused by constructor for `PushVector`. Here is simple example:

```julia
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.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 16, 2019, 8:57pm UTC](https://discourse.julialang.org/t/parametric-outer-constructor/20874/2 "2019-02-16T20:57:00Z")

</div>

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
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`.

---

<div class="post-metadata">

**Author:** ![JaredCrean2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jaredcrean2/32/3574_2.png) [@JaredCrean2](https://discourse.julialang.org/u/JaredCrean2)\
**Post date:** [February 16, 2019, 9:19pm UTC](https://discourse.julialang.org/t/parametric-outer-constructor/20874/3 "2019-02-16T21:19:44Z")

</div>

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

```julia
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

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 16, 2019, 9:53pm UTC](https://discourse.julialang.org/t/parametric-outer-constructor/20874/4 "2019-02-16T21:53:22Z")

</div>

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

> <https://github.com/JuliaLang/julia/blob/a44b421138b4b6e617bccc70270e0fc38c65b81d/base/boot.jl#L397-L420>

It is also alluded to in the docs, in [Constructors · The Julia Language](https://docs.julialang.org/en/v1/manual/constructors/#Parametric-Constructors-1) :

> 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.
