# Understanding type parameters

**URL:** https://discourse.julialang.org/t/understanding-type-parameters/38910
**Category:** New to Julia
**Created:** [May 6, 2020, 7:53pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910 "2020-05-06T19:53:32Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [May 6, 2020, 7:53pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/1 "2020-05-06T19:53:32Z")

</div>

Please help me understand this.

```julia
# unparametrized type
julia> struct Point1
           x:: Int64
           y:: Int64
       end

julia> Point1(1,2)
Point1(1, 2) # OK
# parametrized type
julia> struct Point2{T}
           x::T
           y::T
       end

julia> Point2(1,2)
Point2{Int64}(1, 2) # OK
# parametrized type with an unfortunate parameter name
julia> struct Point3{Real}
           x::Real;
           y::Real;
       end

julia> Point3(1,2)
Point3{Int64}(1, 2) # OK
julia> Point3(1im,1im)
Point3{Complex{Int64}}(0 + 1im, 0 + 1im) # OK

# parametrized struct type with both fixed and parametric fields
julia> struct Point5{T}
           x::Int64
           y::Int64
           z::T
       end

julia> Point5(1,2,3.0)
Point5{Float64}(1, 2, 3.0) # OK

# parametrized struct type with unused type parameter
julia> struct Point6{T}
           x::Int64
           y::Int64
       end

julia> Point6(1,2)
ERROR: MethodError: no method matching Point6(::Int64, ::Int64)

```

The last one is very suprising. Julia had no problem with the unused type parameter in the declaration. One of the automatically generated constructors should have parameters that match the types of the fields. If the struct has two fields with exactly `Int64, Int64` types, then why a constructor was not generated for it?

This is from the official documentation (section “Composite types”):

> When a type is applied like a function it is called a _constructor_ . Two constructors are generated automatically (these are called _default constructors_ ). One accepts any arguments and calls [`convert`](https://docs.julialang.org/en/v1/base/base/#Base.convert) to convert them to the types of the fields, and the other accepts arguments that match the field types exactly. The reason both of these are generated is that this makes it easier to add new definitions without inadvertently replacing a default constructor.

Of course, an unused type parameter has no significance, and should be avoided. But this is very strange. The documentation does not say about special cases where default constructors cannot be generated. I suspect that unused parameter types (unlike unused formal function parameters) should be forbidden by the compiler.

Is this a bug?

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [May 6, 2020, 7:57pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/2 "2020-05-06T19:57:31Z")

</div>

The last one errors because it has no way to infer the type of `T` since nothing you pass in can be bound to it. You can call `Point6{Float64}(1, 2)` if you wish. That will work, or you can define an external constructor `Point6(x::T, y::T) where {T} = Point6{Float64}(x, y)`.

The `Float64` is just an example; the point is that in order to construct `Point6` you need to specify `T` explicitly since none of the fields are bound to `T`. IMO, that should be an error - why would you type parameterize if you don’t need the type - but perhaps there’s a use case for this that I’m missing.

---

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [May 6, 2020, 8:17pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/3 "2020-05-06T20:17:11Z")

</div>

Thank you for your explanation!

Next thing came into my mind is that probably Julia also stores the type parameter with the value. Otherwise how would it know the concrete T for a concrete value? So I have tried:

```julia
julia> p = Point6{Int128}(1,1)
Point6{Int128}(1, 1)

julia> sizeof(p)
16

```

This is amazing! Even though the type parameter `Int128` must be stored somewhere, it is clearly not stored in the value. A an array of 1 million Point6 instances will only occupy 16\*1M bytes.

Magic! 🙂

---

<div class="post-metadata">

### Author: ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)
#### Post date: [May 6, 2020, 8:27pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/4 "2020-05-06T20:27:59Z")

</div>

The type parameter is not necessarily a `DataType` and need not bear any relationship to the types of the fields. For example:

```julia
julia> struct Point7{T} end

julia> p7 = Point7{17}
Point7{17}

```

In your definition you fixed the type of the fields at `Int64` regardless of `T`.

---

<div class="post-metadata">

### Author: ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)
#### Post date: [May 7, 2020, 7:31am UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/5 "2020-05-07T07:31:44Z")

</div>

It may be less magical than you think 🙂

The type parameters are stored in the type itself. I can imagine how it could be useful e.g. you can create a hundred objects and the type parameter is kept only once along with the data type.

```julia
julia> x = Point6{Int128}(1,1)
Point6{Int128}(1, 1)

julia> T = typeof(x)
Point6{Int128}

julia> T.parameters
svec(Int128)

```

---

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [May 7, 2020, 9:05am UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/6 "2020-05-07T09:05:04Z")

</div>

It still feels magical to me. Julia is dynamically typed, but the type information is not stored in the memory that is allocated for values. I don’t know any other language that can do this. Correct me if I’m wrong.

I’m coming from Python and I can tell that a primitive integer value occupies more than a CPU word in memory. An int is an object and it also uses memory to store its type (class). It is probably also true for Javascript (I’m not 100% sure). C and C++ are different, they allocate exactly one CPU word for storing a word. But they are not dynamically typed.

I cannot tell any other dynamically typed language that can store a 64 bit integer value using exactly 64 bits of memory. 🙂

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [May 7, 2020, 3:37pm UTC](https://discourse.julialang.org/t/understanding-type-parameters/38910/7 "2020-05-07T15:37:34Z")

</div>

> [@Laszlo\_Nagy](#):
>
> the type information is not stored in the memory that is allocated for values

It is not very useful to think about it that way. For boxed values, type information is of course [kept around](https://docs.julialang.org/en/v1/devdocs/object/), but when it is determined by the context (eg a method compiled for specific concrete types) there is no need to separately store it.

It is best to leave these details to the language and just aim for [performant code](https://docs.julialang.org/en/v1/manual/performance-tips) by conforming the to the logic of the language.
