# Parametrised Functions in 0.6.0

**URL:** <https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359>\
**Category:** General Usage\
**Created:** [June 20, 2017, 6:01am UTC](https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359 "2017-06-20T06:01:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![joshbode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshbode/32/260_2.png) [@joshbode](https://discourse.julialang.org/u/joshbode)\
**Post date:** [June 20, 2017, 6:01am UTC](https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359/1 "2017-06-20T06:01:07Z")

</div>

In 0.6.0 (released today!), using the new `where` syntax I’m able to define a function `f` as follows:

```julia
0.6.0> abstract type X{T} end

0.6.0> struct A{T} <: X{T} end

0.6.0> struct B{T} <: X{T} end

0.6.0> f(::S) where {T, S <: X{T}} = (S, T)
f (generic function with 1 method)

0.6.0> t = A{Int}()
A{Int64}()

0.6.0> f(t)
(A{Int64}, Int64)

```

Cool!

My question is this: is there a way to specify a function such that I can get at the type (e.g. `A` or `B`) without the parameter applied, e.g. return the value `(A, Int64)`?

I tried the following without success:

```julia
0.6.0> g(::S{T}) where {T, S <: X} = (S, T)
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar

0.6.0> g(::S{T}) where {T, S <: X{T}} = (S, T)
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar

0.6.0> g(::S) where {T, S <: X} = (S, T)
WARNING: static parameter T does not occur in signature for g at REPL[11]:1.
The method will not be callable.
g (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [June 20, 2017, 6:21am UTC](https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359/2 "2017-06-20T06:21:19Z")

</div>

You can’t do it in dispatch (and the property is actually a little ill defined because of type aliases, etc.), but there is

```julia
julia> Base.typename(A{Int}).wrapper
A

```

which also has support in inference, so is efficient to use.

---

<div class="post-metadata">

**Author:** ![joshbode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshbode/32/260_2.png) [@joshbode](https://discourse.julialang.org/u/joshbode)\
**Post date:** [June 20, 2017, 6:24am UTC](https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359/3 "2017-06-20T06:24:48Z")

</div>

Ahh, nice! Thanks for that 🙂

```julia
0.6.0> f(::S) where {T, S <: X{T}} = (Base.typename(S).wrapper, T)
f (generic function with 1 methods)

0.6.0> f(A{Int}()) === (A, Int)
true

```

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [June 21, 2017, 5:14am UTC](https://discourse.julialang.org/t/parametrised-functions-in-0-6-0/4359/4 "2017-06-21T05:14:02Z")

</div>

Keno didn’t quite emphasize this enough:

> [@Keno](#):
>
> and the property is actually a little ill defined because of type aliases

It’s trivial (and fairly common) to observe cases where the `.wrapper` field has no relation to `T`. One correct way to handle a common usage of this pattern is demonstrated by the design of the `similar` functions in base, which demonstrates how to pull apart and recombine types correctly (using dispatch). In the grand tradition of Julia, accessing fields directly with `.` is usually strongly discouraged (although the reasons for this are usually left as an exercise to the reader).
