# Compile-time recognition of parametric types e.g. K{T} for any K

**URL:** <https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041>\
**Category:** General Usage\
**Created:** [May 23, 2020, 7:46pm UTC](https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041 "2020-05-23T19:46:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dataSurfer](https://avatars.discourse-cdn.com/v4/letter/d/67e7ee/32.png) [@dataSurfer](https://discourse.julialang.org/u/dataSurfer)\
**Post date:** [May 23, 2020, 7:46pm UTC](https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041/1 "2020-05-23T19:46:20Z")

</div>

Hi,

I’m don’t know how to get the compiler to recognise a type `K{T}` where K could be any type. For example:

```julia
abstract type AbstractGeneric{T} end
#... after defining further types <: AbstractGeneric{T} for example ... #
struct MyType{T} <: AbstractGeneric{T}
  x::T
end

function myMethod(x::MyType{T}) where {T}
  return 2*x.x
end

# Baby example
 function fun(x::K{T}, z::AbstractArray{T}) where {K <: AbstractGeneric, T <: AbstractFloat}
  return sum((myMethod(x) .- z)^2)
end

```

I specifically want to constrain `K{T}` with `AbstractArray{T}` on `T`. The compiler gives me the error:

```julia
ERROR: TypeError: in Type{...} expression, expected UnionAll, got TypeVar

```

I know that it will compile with:

```julia
 function fun(x::AbstractGeneric{T}, z::AbstractArray{T}) where {T <: AbstractFloat}
  return sum((myMethod(x) .- z)^2)
end

```

But that’s runtime dispatch on `myMethod()` which I don’t want.

Thanks

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [May 23, 2020, 8:30pm UTC](https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041/2 "2020-05-23T20:30:23Z")

</div>

> [@dataSurfer](#):
>
> I specifically want to constrain `K{T}` with `AbstractArray{T}` on `T`

This is a type of dispatch which is not allowed in Julia. The correct way to do it is indeed exactly the second thing you mention, but I didn’t understand this part:

> [@dataSurfer](#):
>
> But that’s runtime dispatch on `myMethod()` which I don’t want.

Do you mean that in this case its its not inferred, so dispatch will happen at runtime? That’s not what I’m seeing. After a small fix to your `fun` by changing `^` to a `.^`, it looks everything is inferred hence dispatch is happening at compile time:

```julia
julia> function fun(x::AbstractGeneric{T}, z::AbstractArray{T}) where {T <: AbstractFloat}
         return sum((myMethod(x) .- z).^2)
       end
fun (generic function with 1 method)

julia> @code_warntype fun(MyType(1.), [1.,2,3])
Variables
  #self#::Core.Compiler.Const(fun, false)
  x::MyType{Float64}
  z::Array{Float64,1}

Body::Float64
1 ─ %1 = Main.myMethod(x)::Float64
...

```

---

<div class="post-metadata">

**Author:** ![dataSurfer](https://avatars.discourse-cdn.com/v4/letter/d/67e7ee/32.png) [@dataSurfer](https://discourse.julialang.org/u/dataSurfer)\
**Post date:** [May 23, 2020, 9:05pm UTC](https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041/3 "2020-05-23T21:05:38Z")

</div>

> [@marius311](#):
>
> Do you mean that in this case its its not inferred, so dispatch will happen at runtime? That’s not what I’m seeing. After a small fix to your `fun` by changing `^` to a `.^` , it looks everything is inferred hence dispatch is happening at compile time:

Yes, that’s what I meant. I should remember to use `@code_warntype`. When I think about it it makes sense or else `AbstractArray` would be dispatching things at run time which would be slow. It’s just that at a glance it looks like runtime polymorphism in any other language. What would be the runtime dispatch equivalent if it exists?

Thank you.

---

<div class="post-metadata">

**Author:** ![dataSurfer](https://avatars.discourse-cdn.com/v4/letter/d/67e7ee/32.png) [@dataSurfer](https://discourse.julialang.org/u/dataSurfer)\
**Post date:** [May 23, 2020, 9:20pm UTC](https://discourse.julialang.org/t/compile-time-recognition-of-parametric-types-e-g-k-t-for-any-k/40041/4 "2020-05-23T21:20:11Z")

</div>

> [@dataSurfer](#):
>
> What would be the runtime dispatch equivalent if it exists?

Answering my own question:

```julia
abstract type AbstractGeneric end
struct MyType <: AbstractGeneric
  x
end
struct MySecondType <: AbstractGeneric
  x
  y
end

function myMethod(x::MyType)
  return 2*x.x
end

function fun(x::AbstractGeneric, z::AbstractArray)
  return sum((myMethod(x) .- z).^2)
end

@code_warntype fun(MyType(3), rand(5))

```

Gives

```julia
@code_warntype fun(MyType(3), rand(5))
Variables
  #self#::Core.Compiler.Const(fun, false)
  x::MyType
  z::Array{Float64,1}

Body::Any
1 ─ %1 = Main.myMethod(x)::Any
│ %2 = Base.broadcasted(Main.:-, %1, z)::Any
│ %3 = Core.apply_type(Base.Val, 2)::Core.Compiler.Const(Val{2}, false)
│ %4 = (%3)()::Core.Compiler.Const(Val{2}(), false)
│ %5 = Base.broadcasted(Base.literal_pow, Main.:^, %2, %4)::Any
│ %6 = Base.materialize(%5)::Any
│ %7 = Main.sum(%6)::Any
└── return %7

```

The compiler substitutes for `Any`.
