# Less verbose way of avoiding type instability?

**URL:** <https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058>\
**Category:** General Usage\
**Created:** [July 25, 2017, 2:39pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058 "2017-07-25T14:39:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [July 25, 2017, 2:39pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/1 "2017-07-25T14:39:10Z")

</div>

I have a simple wrapper type like so:

```julia
struct Wrapper{T <: Real}
	x::AbstractMatrix{T}
	y::AbstractVector{T}
end

```

and a simple function operating on `Wrapper` objects:

```julia
f(w) = w.x * w.y

```

The problem is that `f(w::Wrapper)` seems to be type unstable - red `::Any` in `@code_warntype`, and in my actual use case (more fields in the wrapper type, `f` is not so simple), profiling suggests a fair amount of time spent on type inference.

If the wrapper is parameterized more explicitly, then `f` becomes stable:

```julia
struct WrapperVerbose{T1 <: AbstractMatrix{<:Real}, T2 <: AbstractVector{<:Real}}
	x::T1
	y::T2
end

```

But that’s quite wordy and doesn’t scale nicely when there are more fields.

What’s the preferred way to have type stable functions operating on wrapper types? In performance-sensitive code is it bad to have abstract type annotations on fields? (I did that because sometimes `x` is small and dense, and sometimes it is large and very sparse and using a sparse type helps a lot.)

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 25, 2017, 3:17pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/2 "2017-07-25T15:17:42Z")

</div>

In general, that’s the way to write a wrapper, I don’t think you can escape it. Note that your first definition enforces that the element types of both objects are the same, but the second definition doesn’t.

I wrote a macro to help with parametric definitions:

```julia
julia> using QuickTypes

# _fp stands for fully_parametric
julia> @qstruct_fp WrapperVerbose(x::AbstractMatrix{<:Real}, 
                                  y::AbstractVector{<:Real})

```

It’s equivalent to your second definition, and should be type-stable. Ideally it would support `@qstruct_fp WrapperVerbose{T}(x::AbstractMatrix{T}, ...)` too.

> [@evanfields](#):
>
> In performance-sensitive code is it bad to have abstract type annotations on fields?

Yes.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [July 26, 2017, 5:31pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/4 "2017-07-26T17:31:23Z")

</div>

Yes, indeed, the cause of your troubles is that for composite types, it is very bad (from a performance viewpoint) to have it’s members specified as abstract types. This is because the compiler cannot then make any assumptions about the storage of fields in the object, and thus needs to run checks for every access of the data. A longer explanation is in the documentation: [https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-fields-with-abstract-type-1](https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-fields-with-abstract-type-1)

---

<div class="post-metadata">

**Author:** ![musm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/musm/32/3675_2.png) [@musm](https://discourse.julialang.org/u/musm)\
**Post date:** [July 26, 2017, 10:09pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/5 "2017-07-26T22:09:14Z")

</div>

It might be nice if

```julia
struct Wrapper
	x::AbstractMatrix{<:Real}
	y::AbstractVector{<:Real}
end

```

was sugar for

```julia
struct Wrapper{T <: Real}
	x::AbstractMatrix{T}
	y::AbstractVector{T}
end

```

---

<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:** [July 26, 2017, 10:17pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/6 "2017-07-26T22:17:06Z")

</div>

That would be confusing and prone to performance bugs in my opinion since it becomes difficult to see what the actual parameters are for a struct. Performance bugs because of acidentally leaving out the typeval when wrapping that struct.

---

<div class="post-metadata">

**Author:** ![musm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/musm/32/3675_2.png) [@musm](https://discourse.julialang.org/u/musm)\
**Post date:** [July 26, 2017, 10:24pm UTC](https://discourse.julialang.org/t/less-verbose-way-of-avoiding-type-instability/5058/7 "2017-07-26T22:24:07Z")

</div>

> [@kristoffer.carlsson](#):
>
> That would be confusing and prone to performance bugs in my opinion since it becomes difficult to see what the actual parameters are for a struct. Performance bugs because of acidentally leaving out the typeval when wrapping that struct.

True, that could be problematic. OTOH QuickTypes provides a nice compact syntax for this, so that is probably the better alternative.
