# Function definition with parametric types

**URL:** <https://discourse.julialang.org/t/function-definition-with-parametric-types/106830>\
**Category:** New to Julia\
**Tags:** parametric-types\
**Created:** [November 28, 2023, 9:00am UTC](https://discourse.julialang.org/t/function-definition-with-parametric-types/106830 "2023-11-28T09:00:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![oliviermilla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oliviermilla/32/47200_2.png) [@oliviermilla](https://discourse.julialang.org/u/oliviermilla)\
**Post date:** [November 28, 2023, 9:00am UTC](https://discourse.julialang.org/t/function-definition-with-parametric-types/106830/1 "2023-11-28T09:00:38Z")

</div>

Hello,

It’s a basic question, but it’s still unclear to me.  
What are the functional differences between the function definitions below?

```julia
struct A{T}
end

func(a::A) = #code
func(a<:A) = #code

func(a::A{T}) where {T} = #code
func(a<:A{T}) where {T} = #code

func(a::Type{A}) = #code
func(a::Type{<:A}) = #code

```

Thank you for clearing that up!

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [November 28, 2023, 9:54am UTC](https://discourse.julialang.org/t/function-definition-with-parametric-types/106830/2 "2023-11-28T09:54:33Z")

</div>

```julia
# defined parametric type is abstract, an iterated union
# of parametric concrete types with specific parameter values
# e.g. A{1}, A{:hello}, A{Int}
struct A{T}
end

# calls with arguments of type A may be dispatched to this method
func(a::A) = #code

# this is not valid Julia code, throws syntax error on attempt
func(a<:A) = #code

# arguments of type A, but the method is parameterized by T.
# T is available as a variable in the method body and shared with
# the parameter of an argument type a::A{T}.
# The function call must provide a known T value to dispatch to this.
# Parameters are the go-to way of using compile-time information,
# since methods are compiled on type signatures.
func(a::A{T}) where {T} = #code

# not valid code, same error
func(a<:A{T}) where {T} = #code

# the instance of Type{A} is A, so the only argument you can pass is A
# not any concrete subtypes with specified parameters, only A
func(a::Type{A}) = #code

# Type{<:A} is shorthand for (Type{S} where S<:A)
# So any subtype of A, including A itself, is accepted.
# This is not a parametric method because the method itself does not
# have a parameter, only an argument type.
func(a::Type{<:A}) = #code

```

---

<div class="post-metadata">

**Author:** ![oliviermilla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oliviermilla/32/47200_2.png) [@oliviermilla](https://discourse.julialang.org/u/oliviermilla)\
**Post date:** [November 28, 2023, 10:03am UTC](https://discourse.julialang.org/t/function-definition-with-parametric-types/106830/3 "2023-11-28T10:03:42Z")

</div>

Well, Benny, you made it perfectly clear. Thank you. 🙏

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [November 28, 2023, 10:11am UTC](https://discourse.julialang.org/t/function-definition-with-parametric-types/106830/4 "2023-11-28T10:11:28Z")

</div>

Oh, probably worth mentioning this too, `<:` goes in where clauses of definitions, which is probably what you need to know to avoid those syntax errors. This is treated differently from the `<:` binary operator you can call in running code.

```julia
# V this serves as where clause for struct, despite lack of where
struct A{T}
end

# V no V yes for method
func(a::A{T}) where {T} = # code

# V yes for type, shorthand form
func(a::Type{<:A}) = # code

# V yes for type, full form
func(a::Type{S} where {S<:A}) = # code

```
