# Type Alias for parametric type

**URL:** <https://discourse.julialang.org/t/type-alias-for-parametric-type/18337>\
**Category:** New to Julia\
**Tags:** parametric-types\
**Created:** [December 5, 2018, 5:07pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337 "2018-12-05T17:07:21Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ajp](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@ajp](https://discourse.julialang.org/u/ajp)\
**Post date:** [December 5, 2018, 5:07pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/1 "2018-12-05T17:07:21Z")

</div>

Hi, Could someone explain what’s is going on here?

```julia
module test

struct Stuff{A, B, C, D}
   a::A
   b::B
   c::C
   d::D
   Stuff{A, B, C, D}(v1, v2, v3, v4) where {A, B, C, D} = new(v1, v2, v3, v4)
end

function func1(s::Stuff{A, B, C, D}) where {A, B, C, D}
  println(s.a, " ", typeof(s.a))
  println(s.b, " ", typeof(s.b))
  println(s.c, " ", typeof(s.c))
  println(s.d, " ", typeof(s.d))
end

stuff = Stuff{Int64, Float64, Bool, String}(1, 1.0, false, "hello")

func1(stuff)	    

# found that this also works... 

const S = Stuff{A, B, C, D} where {A, B, C, D}
function func2(s::S)
  println(s.a, " ", typeof(s.a))
  println(s.b, " ", typeof(s.b))
  println(s.c, " ", typeof(s.c))
  println(s.d, " ", typeof(s.d))
end

func2(stuff)
end

```

With reference to func2, I’ve found I can define a type alias for complex parametric types that greatly cleans up the function signature. That being said, I’m not sure I understand the placement of the “where” syntax in func1, since for a crude find and replace (I know that’s not what’s its doing) the where syntax would be within the function argument not afterwards. Is what I’m doing legal and performant? Is it recommended? I have to be honest when I started learning Julia (about 2 weeks ago) I just iterated my syntax for parametric types and the “where” until I got it working. I don’t really get what it’s doing for undefined types like A, B etc or if I should be doing something better.

I come from c++ I can’t help thinking {A, B, C, D} as the template types, but I have no analogy for “where {A, B, C, D}” and so can’t really get my head round it…any help appreciated.

Thanks,  
Andy

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 5, 2018, 5:16pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/2 "2018-12-05T17:16:04Z")

</div>

`where` sets bound on given parameters. Since you did not bound parameters, `Stuff`, and `S` are the same thing.

---

<div class="post-metadata">

**Author:** ![ajp](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@ajp](https://discourse.julialang.org/u/ajp)\
**Post date:** [December 5, 2018, 5:30pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/3 "2018-12-05T17:30:11Z")

</div>

I have interpreted that to mean the bounds are optional and therefore so is the “where”, but for the constructor say, missing the “where” does not work:

```julia
Stuff{A, B, C, D}(v1, v2, v3, v4) = new(v1, v2, v3, v4)

```

Likewise for func1, defining it as:

```julia
function func1(s::Stuff{A, B, C, D})
  println(s.a, " ", typeof(s.a))
....

```

does not work. Could I enquire therefore what bounds exactly have I conferred on types {A, B, C, D} by simply adding “where {A, B, C, D}”? There is no new information there, type or bounds? What purpose does it serve here apart from to get it to work: which currently is the only reason I’m adding it. In my real code I’m adding it simply to get it to compile not because I prepend any additional type or bounds information in doing so.

I presume you’re going to say something like this:

```julia
function func1(s::Stuff{A, B, C, D}) where {A<:Int, B<:Real, C, D}

```

which does indeed work and in this instance I assume you mean applies some bounds to the types. My point/question is: when I do not have that additional clarity, or do not wish to provide it, is the code:  
a) less performant if it’s missing? In terms of type-stability, or speed?  
b) what’s the purpose if no additional information is provided and is there a short-circuit to skip it if I do not intend to bound the types?  
c) is there an alternative more compact syntax that does the same thing if there is no short-circuit?

Thanks,  
Andy

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 5, 2018, 5:43pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/4 "2018-12-05T17:43:12Z")

</div>

You can skip unused parameters from the end of parameter list such as you can use  
`Stuff{T,S} where {T<:Real, S<:Real}` to mean `s::Stuff{A, B, C, D} where {A, B, C\<:Real, D\<:Real}. In the case of your function,

```julia
function func1(s::Stuff)
 println(s.a, " ", typeof(s.a))
....

```

without any parameters, is the signature you want. For the short hand, `Stuff{<:Int <:Real,<:Any, <:Any}` is the signature you could use in the last example if the parameters are not used in the function body.  
Edit: By the way, the type unstability comes from usage of variables in the function body so the function signature does not matter in this sense. But there can be edge cases I don’t know. I suggest reading [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#UnionAll-Types-1) for `where` syntax.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 5, 2018, 5:57pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/5 "2018-12-05T17:57:34Z")

</div>

Also, more on the constructors, [Constructors · The Julia Language](https://docs.julialang.org/en/v1/manual/constructors/#Inner-Constructor-Methods-1) .

---

<div class="post-metadata">

**Author:** ![ajp](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@ajp](https://discourse.julialang.org/u/ajp)\
**Post date:** [December 5, 2018, 6:35pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/6 "2018-12-05T18:35:03Z")

</div>

Thanks. So without parameters as opposed to a) the alias or b) all the parameter types specified at least the aritty, is in no way slower? It doesn’t incur a cost for not specifying them?

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 5, 2018, 6:52pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/7 "2018-12-05T18:52:19Z")

</div>

No, not at all. The type stability is not affected and Julia will try to compile all the way what your input types will be in running time. However, as I said there are some rare edge cases that compiler quit specializing on but they are different story.

---

<div class="post-metadata">

**Author:** ![ajp](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@ajp](https://discourse.julialang.org/u/ajp)\
**Post date:** [December 5, 2018, 7:54pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/8 "2018-12-05T19:54:50Z")

</div>

Is speed effected then if type stability is not ? I’m still not sure I grasp this. If it has no effect why provide the type in the first place? This is counterintuitive if true. A purpose of the types (for which the parameters are part of, they must be) is to ensure speed.

What about if the parameter types are used in the function? They must be required then?

How do I refer to a the part of a composite parameter type such as Stuff for which I only provide the Stuff part of the name qualifier? In your example then how do I refer to the “Stuff” part of the name when i exclude the parameter types? It can’t be referred to as the type it’s missing information (A, B etc)? In c++ the type would be undefined without the parameters simply a template, you are making me think this is not the case here. Totally fine with that it’s a different language just want a concrete answer.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 6, 2018, 4:33am UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/9 "2018-12-06T04:33:02Z")

</div>

As long as your input types in running time are concrete, Julia will infer types of each variable in the function body and if it is sure that variables don’t change type, overall code will be type stable. On the other hand, having type bounds in function decleration is more about method dispatch. Julia will choose the most specific method of that function depending on your input types. In other words, for some aritty, you can decide specializing a better method and use the type bounds to dispatch to this method.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 6, 2018, 1:17pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/10 "2018-12-06T13:17:18Z")

</div>

> [@ajp](#):
>
> . If it has no effect why provide the type in the first place? This is counterintuitive if true. A purpose of the types (for which the parameters are part of, they must be) is to ensure speed.

Not necessarily. When you specify the type of a function argument in Julia, the only thing you’re doing is _controlling dispatch_. That is, you are determining what the (potentially arbitrarily large) set of types you want your function to be applicable to is. For example, to write a function that operates on all types which are `<:Real`, you simply do:

```julia
function foo(x::Real)
    ...
end

```

And if you want some other behavior of `foo` for types which are specifically integers, you also do:

```julia
function foo(x::Integer)
  ...
end

```

Crucially, the fact that `Real` and `Integer` are both abstract types has _no effect on performance_. When you call `foo(1.0)`, Julia compiles a specialized method of `foo` for exactly the actual concrete types of the arguments. In the case of `foo(1.0)`, this would mean using your definition from `foo(x::Real)` (the most specific applicable method) to compile a concrete specialization with the type of `x` set to `Float64` (which is the concrete type of `1.0`).

This is exactly what’s happening in your original case. It’s totally fine for performance to write a function like:

```julia
function foo(s::Stuff)
  ...
end

```

even though `Stuff` on its own is not a concrete type. When you pass some value into that function, Julia will compile a specialized version using the concrete type of that value.

This may be easier to understand with some clarity about what parametric types are in Julia. On its own, `Stuff` is not a type, but a union of types. We can verify this at the REPL:

```julia
julia> Stuff === Stuff{A, B, C, D} where {A, B, C, D}
true

```

So when you write:

```julia
function foo(s::Stuff)
 ...
end

```

you could equivalently write `foo(s::Stuff{A, B, C, D} where {A, B, C, D})`. Or you can do:

```julia
const S = Stuff{A, B, C, D} where {A, B, C, D}

```

as you did above, but that alias is not particularly helpful, because all you’ve done is make `S === Stuff`:

```julia
julia> const S = Stuff{A, B, C, D} where {A, B, C, D}
Stuff

julia> S === Stuff
true

```

However, if you want to access the type parameters inside the function body, then you need to essentially move the `where` clause outward, applying that `where` to the entire function body instead of just one argument:

```julia
function foo(s::Stuff{A, B, C, D}) where {A, B, C, D}
  <do stuff with A, B, C, or D>
end

```

There’s a final point which has gotten mixed up here involving specifying only a subset of the type parameters. This is also easier to explore interactively:

```julia
julia> Stuff{Int, Int, Int} === Stuff{Int, Int, Int, D} where {D}
true

julia> Stuff{Int, Int} === Stuff{Int, Int, C, D} where {C, D}
true

julia> Stuff{Int} === Stuff{Int, B, C, D} where {B, C, D}
true

```

---

<div class="post-metadata">

**Author:** ![ajp](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@ajp](https://discourse.julialang.org/u/ajp)\
**Post date:** [December 6, 2018, 1:26pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/11 "2018-12-06T13:26:03Z")

</div>

That is extremely helpful!

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 6, 2018, 1:43pm UTC](https://discourse.julialang.org/t/type-alias-for-parametric-type/18337/12 "2018-12-06T13:43:50Z")

</div>

> [@rdeits](#):
>
> There’s a final point which has gotten mixed up here involving specifying only a subset of the type parameters. This is also easier to explore interactively:
> 
> ```julia
> julia> Stuff{Int, Int, Int} === Stuff{Int, Int, Int, D} where {D}
> true
> 
> julia> Stuff{Int, Int} === Stuff{Int, Int, C, D} where {C, D}
> true
> 
> julia> Stuff{Int} === Stuff{Int, B, C, D} where {B, C, D}
> true
> 
> ```

Thanks for the correction. I thought parameters start being defined from the end of the parameters list.
