# Order of parameters in outer constructor matters?

**URL:** <https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367>\
**Category:** New to Julia\
**Tags:** question, parametric-types, constructors\
**Created:** [July 17, 2022, 7:11pm UTC](https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367 "2022-07-17T19:11:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ac1643](https://avatars.discourse-cdn.com/v4/letter/a/a6a055/32.png) [@ac1643](https://discourse.julialang.org/u/ac1643)\
**Post date:** [July 17, 2022, 7:11pm UTC](https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367/1 "2022-07-17T19:11:00Z")

</div>

I am playing around with parametric types and constructors. First I have a type and constructor as

```julia
julia> struct Foo{T, N}
           val::T
       end

julia> function Foo{N}() where {N}
           return Foo{Int, N}(1)
       end

```

Calling this new constructors works as expected:

```julia
julia> Foo{2}()
Foo{Int64, 2}(1)

```

If I want the first parameter to be a subtype of `Integer`, I do it like this:

```julia
julia> struct Bar{T<:Integer, N}
           val::T
       end

julia> function Bar{N}() where {N}
           return Bar{Int, N}(1)
       end

```

Trying to do the same thing as with the Foo constructor I get an error:

```julia
julia> Bar{2}()
ERROR: TypeError: in Bar, in T, expected T<:Integer, got a value of type Int64
Stacktrace:
 [1] top-level scope
   @ REPL[20]:1

```

However, if I swap the parameters

```julia
julia> struct Baz{N, T<:Integer}
           val::T
       end

julia> function Baz{N}() where {N}
           return Baz{N, Int}(1)
       end

```

things work just fine

```julia
julia> Baz{2}()
Baz{2, Int64}(1)

```

Why is this the case?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [July 17, 2022, 9:15pm UTC](https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367/3 "2022-07-17T21:15:05Z")

</div>

Try an alias.

```julia
julia> struct Bar{T <: Integer, N}
           val::T
       end

julia> const IntBar{N} = Bar{Int, N} where N
IntBar (alias for Bar{Int64})

julia> IntBar{2}(1)
IntBar{2}(1)

julia> IntBar{N}() where N = IntBar{N}(1)

julia> IntBar{2}()
IntBar{2}(1)

```

---

<div class="post-metadata">

**Author:** ![ac1643](https://avatars.discourse-cdn.com/v4/letter/a/a6a055/32.png) [@ac1643](https://discourse.julialang.org/u/ac1643)\
**Post date:** [July 18, 2022, 4:55am UTC](https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367/4 "2022-07-18T04:55:39Z")

</div>

That is a solution but not for what I had in mind, I’m sorry I did not specify more clearly before. What I would like from the outer constructor is to declare the type of the field `val` implicitly, like so

```julia
julia> struct Foo{T <: Integer, N}
           val::T
       end

julia> function Foo{N}(val::T) where {N, T}
           return Foo{T, N}(val)
       end

```

Here the same error is thrown, but if I change the order of the parameters in the declaration of `Foo`, then, there is no problem.

I tried to so the same thing done in this document I found online [here.](https://github.com/icme/cme257-advanced-julia/blob/master/class/class2/class2.ipynb) At `In [20]`, he defines the parametric type for a finite field with characteristic N, but the order of the parameters seemed weird, compared to other Julia code I have seen. Does the order matter in this case, and if it does, why?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [July 19, 2022, 1:11pm UTC](https://discourse.julialang.org/t/order-of-parameters-in-outer-constructor-matters/84367/5 "2022-07-19T13:11:04Z")

</div>

The crux of the issue, as far as I get, is that `Bar{N}` is just an alias for `Bar{N, K} where {K}`.

So, effectively, Julia parses the function definition as

```julia
julia> struct Bar{T<:Integer, N}
           val::T
       end

julia> function (Bar{N, P} where {P})() where {N}
           return Bar{Int, N}(1)
       end

```

This is why you can’t call `Bar{2}` at all if the first type parameter of `Bar` is constrained to a subtype of `Integer`.
