# Is there a difference between \`T::Type\` and \`::Type{T} ... where T\` in a method si

**URL:** <https://discourse.julialang.org/t/is-there-a-difference-between-t-type-and-type-t-where-t-in-a-method-si/55825>\
**Category:** General Usage\
**Created:** [February 23, 2021, 6:20am UTC](https://discourse.julialang.org/t/is-there-a-difference-between-t-type-and-type-t-where-t-in-a-method-si/55825 "2021-02-23T06:20:39Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BridgeBot](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bridgebot/32/21491_2.png) [@BridgeBot](https://discourse.julialang.org/u/BridgeBot)\
**Post date:** [February 23, 2021, 6:20am UTC](https://discourse.julialang.org/t/is-there-a-difference-between-t-type-and-type-t-where-t-in-a-method-si/55825/1 "2021-02-23T06:20:39Z")

</div>

Is there a difference between `T::Type` and `::Type{T} ... where T` in a method signature?

Note that the original poster on Slack cannot see your response here on Discourse. Consider _transcribing the appropriate answer back to Slack_, or pinging the poster here on Discourse so they can _follow this thread_.  
[(Original message :slack:)](https://julialang.slack.com/archives/C6A044SQH/p1614045063170500?thread_ts=1614045063.170500&cid=C6A044SQH) [(More Info)](https://github.com/JuliaCommunity/SlackBridge)

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 23, 2021, 6:24am UTC](https://discourse.julialang.org/t/is-there-a-difference-between-t-type-and-type-t-where-t-in-a-method-si/55825/2 "2021-02-23T06:24:16Z")

</div>

Answer: Yes, and it’s due to specialization.

`T::Type` allows the compiler to decide if it needs to specialize or not. If T is used in the function body, it will do so. If T is passed through to another function, it will not.

`::Type{T} ... where T` forces the compiler to specialize the function.

Specialization means a separate method is created and compiled for each new type passed to the function. If the method doesn’t do anything special _hint hint_ based on the type, then there’s probably no benefit to doing this, with potentially substantial cost. The behavior is described here: [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing)

Thanks to @jakobnissen @mkitti @Mason for the information!

---

<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:** [February 23, 2021, 7:26am UTC](https://discourse.julialang.org/t/is-there-a-difference-between-t-type-and-type-t-where-t-in-a-method-si/55825/3 "2021-02-23T07:26:24Z")

</div>

Great question.

I also posted on using the `methods` method to see what specializations were happening or not happening. This is how I check myself to see if I understand what Julia is doing under-the-hood.

Here’s the version with no specialization:

```julia
julia> f(T::Type) = T
f (generic function with 1 method)
julia> methods(f).ms[1].specializations
svec()
julia> f(Int64)
Int64
julia> methods(f).ms[1].specializations
svec(#undef, #undef, #undef, #undef, #undef, #undef, #undef, MethodInstance for f(::Type{T} where T))

julia> f(Float64)
Float64

julia> methods(f).ms[1].specializations
svec(#undef, #undef, #undef, #undef, #undef, #undef, #undef, MethodInstance for f(::Type{T} where T))

```

Despite calling `f` with both `Int64` and `Float64` as arguments, only a single `MethodInstance` is needed to handle both arguments.

Here is the version with specialization:

```julia
julia> g(::Type{T}) where T = T
g (generic function with 1 method)
julia> methods(g).ms[1].specializations
svec()
julia> g(Int64)
Int64
julia> methods(g).ms[1].specializations
svec(MethodInstance for g(::Type{Int64}), #undef, #undef, #undef, #undef, #undef, #undef, #undef)
julia> g(Float64)
Float64
julia> methods(g).ms[1].specializations
svec(MethodInstance for g(::Type{Int64}), MethodInstance for g(::Type{Float64}), #undef, #undef, #undef, #undef, #undef, #undef)

```

Now we have a `MethodInstance` that is specialized for `Int64` and another `MethodInstance` that is specialized for `Float64`.

`methods` returns a `Base.MethodList` with two fields, `ms` and `mt`. `ms` is just a `Vector{Method}`. `mt` is a `Core.MethodTable`. Both contain a wealth of information about the resulting methods.
