# Unnecessary type parameters

**URL:** <https://discourse.julialang.org/t/unnecessary-type-parameters/49100>\
**Category:** Internals & Design\
**Created:** [October 27, 2020, 7:08am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100 "2020-10-27T07:08:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lijas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lijas/32/20023_2.png) [@lijas](https://discourse.julialang.org/u/lijas)\
**Post date:** [October 27, 2020, 7:08am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/1 "2020-10-27T07:08:33Z")

</div>

Quite often I have to use the type parameters to make the struct concrete/type stable, but I never need to use that parameter for dispatch. So the type parameter becomes unnecessary in some sense (and ugly). For example

```julia
abstract struct AType end
struct Subtype1 <: Atype end
struct Subtype2 <: Atype end

struct Othertype{T<:AType}
    s::T
end

```

If I would have

```julia
struct Othertype
    s::AType
end

```

OtherType(Subtype1()) would not be concrete.

I feel like one should be able to do as in the second version, and still have it type stable, instead of caring around unnecessary type parameters.

I know there are probobly macros that can help with this, but I am more interested in what is the reasoning not have it in the language by default 😛

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [October 27, 2020, 8:14am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/2 "2020-10-27T08:14:14Z")

</div>

> I feel like one should be able to do as in the second version, and still have it type stable, instead of caring around unnecessary type parameters.

But non concrete types such as `AType` can not lead to concrete structs by definition. Not sure why you find the type parameter to be unnecessary here?

In particular consider this:

```julia
julia> abstract type AType end
       struct Subtype1 <: AType end
       struct Subtype2 <: AType end

       struct Othertype{T<:AType}
           s::T
       end
julia> struct Othertype2
         s :: AType
       end

```

and check the inferred element types of arrays of `Othertype` and `Othertype2`:

```julia
julia> using Test

julia> @inferred [Othertype2(Subtype1()), Othertype2(Subtype2())][1]
Othertype2(Subtype1())

julia> @inferred [Othertype(Subtype1()), Othertype(Subtype2())][1]
ERROR: return type Othertype{Subtype1} does not match inferred return type Othertype

```

This indicates that the compiler knows the element type exactly for `Othertype2` but not for `Othertype`. There might be occasions where you want the compiler to have this information.

Here’s an aside that you might want to consider:  
Methods for structs with type-parameters would need to be re-compiled for each combination, whereas they won’t need to be if the struct isn’t concretely typed. The language allows this.

```julia
julia> struct MyReal
           s::Real
       end

julia> Base.:(+)(a::MyReal, b::MyReal) = MyReal(a.s + b.s)

julia> MyReal(1) + MyReal(3.0)
MyReal(4.0)

julia> MyReal(1) + MyReal(3)
MyReal(4)

julia> struct MyRealConcrete{T<:Real}
           s::T
       end

julia> Base.:(+)(a::MyRealConcrete, b::MyRealConcrete) = MyRealConcrete(a.s + b.s)

julia> MyRealConcrete(1) + MyRealConcrete(3.0)
MyRealConcrete{Float64}(4.0)

julia> MyRealConcrete(1) + MyRealConcrete(3)
MyRealConcrete{Int64}(4)

```

In the first case the function `+` needs to be compiled just once for `MyReal` arguments, whereas in the second case it’ll need to be compiled for each combination of `MyRealConcrete{T}`. Performance will likely be better with the latter, but there might be occasions where you want the former.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [October 27, 2020, 9:06am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/3 "2020-10-27T09:06:02Z")

</div>

I agree:

> [@Addition to parameter of parametric type](https://discourse.julialang.org/t/addition-to-parameter-of-parametric-type/20059/9):
>
> One issue I have with Julia’s type parameters, related to this, is that some of them are part of the public API and some of them are private. For above example A might be public, but B isn’t. Another one is: julia\> typeof(1.0:0.1:0.9) StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} Where the first parameter is public (you would potentially use it for dispatch) but the second two are internal ones (I think calculated from the first somehow but I’m not sure). I…

---

<div class="post-metadata">

**Author:** ![lijas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lijas/32/20023_2.png) [@lijas](https://discourse.julialang.org/u/lijas)\
**Post date:** [October 27, 2020, 9:27am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/5 "2020-10-27T09:27:04Z")

</div>

_Woops, replied to wrong post._  
Ok, so I can see that there are instances where both options are useful.

The reason I want to make everything concrete, is because I notice better performance in my code.

What I mean with “unnecessary” is that I will never need to dispatch on the type parameter, it just there to make it concrete/get better performance. For example, In my code I have a struct (lets call it “MyStruct”) with like 4-5 fields, and I need to have their types as type parameters, which makes for extra code. Also when getting errors, the stacktrace takes up like 5 rows because the type-name becomes so long, making it difficult to read the error etc. Furthermore, if I need MyStuct as a field in some other struct, I need to make its type an type-parameter aswell, so basically everything gets put in the type field all the time 😛

I think there is a package that solves this using macros, but it works by putting it as type parameters. It would be nice if the compiler could keep track of some of the types “in the background” without having them as type parameters.

```julia
struct MyType{A<:A1, B<:A2, C<:A3}
a::A 
b::B
c::C
end

```

instead of

```julia
struct MyType
@concrete a::A1
@concrete b::A2
@concrete c::A3
end

```

---

<div class="post-metadata">

**Author:** ![lijas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lijas/32/20023_2.png) [@lijas](https://discourse.julialang.org/u/lijas)\
**Post date:** [October 27, 2020, 9:42am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/6 "2020-10-27T09:42:45Z")

</div>

That thread includes a lot of what my question was about, thanks. To bad it seems like it will possibly first be implemented in 2.0.

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [October 27, 2020, 9:42am UTC](https://discourse.julialang.org/t/unnecessary-type-parameters/49100/7 "2020-10-27T09:42:58Z")

</div>

Checkout [[ANN] ConcreteStructs.jl - Cut the boilerplate when concretely parameterizing structs](https://discourse.julialang.org/t/ann-concretestructs-jl-cut-the-boilerplate-when-concretely-parameterizing-structs/47274)
