# Parametric type: type stable getfield

**URL:** https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880
**Category:** New to Julia
**Tags:** parametric-types, type-stability
**Created:** [September 12, 2018, 9:07pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880 "2018-09-12T21:07:15Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ric.cioffi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ric.cioffi/32/18373_2.png) [@ric.cioffi](https://discourse.julialang.org/u/ric.cioffi)
#### Post date: [September 12, 2018, 9:07pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/1 "2018-09-12T21:07:15Z")

</div>

Hi everyone,  
I have a bit of trouble understanding what is going on and why I’m getting type instability (julia 0.7).

I create a parametric type of the form

```julia
mutable struct Point{T1<:Real}
    x::T1
    y::Int64
end

```

Now this is type stable:

```julia
p = Point(1,1)
@code_warntype p.x

```

while this isn’t:

```julia
p = Point(1.5,1)
@code_warntype p.x

```

In particular, why do I get that Union? I’m just getting started on 0.7 and, if I understood correctly I don’t have to worry too much about this union. Still, i’d like to understand what exactly is going on.

Thanks a lot 🙂

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [September 12, 2018, 9:17pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/2 "2018-09-12T21:17:40Z")

</div>

Put things in functions for optimizations to properly kick in.

```julia
julia> f(p) = p.x
f (generic function with 1 method)

julia> @code_warntype f(p)
Body::Float64
1 1 ─ %1 = (Base.getfield)(p, :x)::Float64 │╻ getproperty
  └── return %1     

```

The reason it infers when all fields are the same type is, well, all fields are the same type.

---

<div class="post-metadata">

### Author: ![ric.cioffi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ric.cioffi/32/18373_2.png) [@ric.cioffi](https://discourse.julialang.org/u/ric.cioffi)
#### Post date: [September 12, 2018, 9:24pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/3 "2018-09-12T21:24:37Z")

</div>

Cool, but why does that not work if not in a function? Should’t the compiler know the type of p.x anyway?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [September 12, 2018, 9:27pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/4 "2018-09-12T21:27:08Z")

</div>

`p.x` is the same as `getproperty(p, :x)` so what happens in your case is similar to:

```julia
julia> f(p, s) = getproperty(p, s)
f (generic function with 2 methods)

julia> @code_warntype f(p, :x)
Body::Union{Float64, Int64}
1 1 ─ %1 = (Base.getfield)(p, s)::Union{Float64, Int64} │╻ getproperty
  └── return %1 │

```

In other words, the `.x` is not considered a constant from the way you use the macro.

In fact, we can see what the macro expands to:

```julia
julia> @macroexpand @code_warntype p.x
:((InteractiveUtils.code_warntype)(getproperty, (Base.typesof)(p, :x)))

```

and

```julia
julia> (Base.typesof)(p, :x)
Tuple{Point{Float64},Symbol}

```

so we end up calling

```julia
julia> code_warntype(getproperty, Tuple{Point{Float64},Symbol})
Body::Union{Float64, Int64}
18 1 ─ %1 = (Base.getfield)(x, f)::Union{Float64, Int64} │
   └── return %1    

```

where it is clear that the “constness” of `.x` is lost.

---

<div class="post-metadata">

### Author: ![ric.cioffi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ric.cioffi/32/18373_2.png) [@ric.cioffi](https://discourse.julialang.org/u/ric.cioffi)
#### Post date: [September 12, 2018, 9:42pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/5 "2018-09-12T21:42:16Z")

</div>

Great, that explains it. Thanks a lot.

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [October 30, 2018, 10:12pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/6 "2018-10-30T22:12:40Z")

</div>

I also encounter a similar problem if I want to define my own “get” for a 2 layered nested structure. My question is does this kind of code warn type has an implication for performance? In other word, it is fine not make my own get function type stable.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 30, 2018, 10:21pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/7 "2018-10-30T22:21:50Z")

</div>

It can have an impact on performance, yes. Regarding your specific problem, a bit more information would help.

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [October 30, 2018, 11:11pm UTC](https://discourse.julialang.org/t/parametric-type-type-stable-getfield/14880/8 "2018-10-30T23:11:27Z")

</div>

Hi, here is what I am trying to do

```julia
abstract type AbstractParticleProperties end

mutable struct Particle{N, S, T}
   properties::ParticleProperties{N, T}
   states::ParticleStates{S, T}
end

mutable struct ParticleProperties{N <:Int, T <:Real} <:AbstractParticleProperties
   id::N
   mass::T  
  #More fields ...
end

mutable struct ParticleStates{S <:Int, T <:Real} 
   x::SVector{S, T}
   f::SVector{S, T}
 #More fields...
end

```

In my code I typically need to access kind or id of a particle (an instance of Particle). Originally, my desire was that I don’t want to always write particle.properties.(some field in particle properties). So I implement sth like

```julia
function get_properties_field(particle::Particle{N, S, T}, s::Symbol) where {N, S, T}
    getfield(getfield(particle, properties), s)
end

```

which I discovered that it is not typed stable. After reading what you have described, I implements sth like this instead

```julia
function id(particle::Particle{N, S, T}) where {N, S, T}
    particle.properties.id
end

```

When I measure the performance, it turns out that the second version performance a lot better 🙂 . However, this means that I have to write sth like this for every fields in the ParticleProperties. Moreover, every time that I want  
create a subtype of AbstractParticleProperties with a different field, says electric charge. I have to implement sth like above again. Is there a nice way work around this? Alternatively, I don’t have to think about this problem just use p.properties.(whatever). Hopefully, this clarify up my question above.
