# Isbits Without Propagation of Parametric Types?

**URL:** <https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305>\
**Category:** General Usage\
**Tags:** question, parametric-types\
**Created:** [August 12, 2021, 10:46pm UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305 "2021-08-12T22:46:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ian\_Slagle](https://avatars.discourse-cdn.com/v4/letter/i/b5a626/32.png) [@Ian\_Slagle](https://discourse.julialang.org/u/Ian_Slagle)\
**Post date:** [August 12, 2021, 10:46pm UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305/1 "2021-08-12T22:46:30Z")

</div>

Consider this MWE:

```julia
abstract type A end
abstract type B <: A end
abstract type C <: A end

struct D{T <: A}
    data::UInt8
end

struct E
    a::D
    b::D
    c::D
end

struct F{T1 <: D, T2 <: D, T3 <: D}
    a::T1
    b::T2
    c::T3
end

@assert !isbits(E(D{B}(0x00), D{C}(0x00), D{B}(0x00)))
@assert isbits(F{D{B}, D{C}, D{B}}(D{B}(0x00), D{C}(0x00), D{B}(0x00)))

```

Is it possible to modify E to be isbits without having to specify all of the types within it? In the real example, I basically have two layers that contain several E’s that would otherwise be isbits, and I never use the parameters in function specialization except when passing a, b, and c themselves into functions. I’m new to parametric types, so this might not make sense

---

<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:** [August 13, 2021, 7:59am UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305/2 "2021-08-13T07:59:43Z")

</div>

> [@Ian\_Slagle](#):
>
> this might not make sense

I concur, I don’t understand what the question is.

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 13, 2021, 8:03am UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305/3 "2021-08-13T08:03:54Z")

</div>

This sounds like an [XY problem - Wikipedia](https://en.wikipedia.org/wiki/XY_problem) to me. Can you be more specific?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 13, 2021, 8:46am UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305/4 "2021-08-13T08:46:15Z")

</div>

`D` on its own is not a concrete type, it’s a `UnionAll`, whereas the parametrized version is a concrete type:

```julia
julia> typeof(D)
UnionAll        

julia> typeof(D{B})
DataType             

julia> isconcretetype(D{B})
true                       
                           
julia> isconcretetype(D)   
false                      

```

Julia does not know just from looking at the field in `E` that you’re never using the parameter of `D` inside of `D` - however, that has no bearing on what you _could_ do with it in a function though. Consider (I believe that’s what you’re doing, yes?):

```julia
julia> f(e) = g(e.a)               
f (generic function with 1 method) 
                                   
julia> g(::D{B}) = "B"             
g (generic function with 1 method) 
                                   
julia> g(::D{C}) = "C!"            
g (generic function with 2 methods)
                                   
julia> f(E(D{B}(0x0^C              
                                   
julia> struct F # just to make this a little easier to read
           a::D                    
       end                         
                                   
julia> f(F(D{B}(0x0)))             
"B"                                
                                   
julia> f(F(D{C}(0x0)))             
"C!"                               

julia> isbitstype(F)
false               

```

In other words, the type information of its parameter isn’t lost when only specifying `D` in `E` (or another struct for that matter). The result is that the field has to be boxed to accomodate the extra type tag for dynamic dispatch.

If you check `@code_warntype f(F(D{C}(0x0)))`, you’ll also see that julia tells you about only knowing the `UnionAll` `D` and marks it red to signify that this will cause dynamic dispatch.

---

<div class="post-metadata">

**Author:** ![Ian\_Slagle](https://avatars.discourse-cdn.com/v4/letter/i/b5a626/32.png) [@Ian\_Slagle](https://discourse.julialang.org/u/Ian_Slagle)\
**Post date:** [August 13, 2021, 7:56pm UTC](https://discourse.julialang.org/t/isbits-without-propagation-of-parametric-types/66305/5 "2021-08-13T19:56:01Z")

</div>

> [@Tamas\_Papp](#):
>
> I concur, I don’t understand what the question is.

Apologies! I’ll try to elaborate

> [@tamasgal](#):
>
> This sounds like an [XY problem - Wikipedia](https://en.wikipedia.org/wiki/XY_problem) to me. Can you be more specific?

I agree. Here’s the real (Y) problem. I was inspired by this post ([Julia used Multiple Dispatch! It's Super Effective! - Moll.dev](https://www.moll.dev/projects/effective-multi-dispatch/)) to try to use multiple dispatch for effectiveness in a full Pokemon model. The problem is that in the full model, types have their own moves, and Pokemon themselves can have one or two types. My solution is contained in `team/damage.jl` and `team/data.jl` of this repository: [GitHub - pvpisistratus/RandomBattles.jl: PoGo PvP Battles simulated with random players, or models based on random players](https://github.com/pvpisistratus/RandomBattles.jl)

This implementation still re-uses a lot of code (maybe it doesn’t have to, but that’s a different question), but more importantly it comes with a steep performance hit and also makes the entire StaticState not able to be isbits (my assumption is that the two are related).

> [@Sukera](#):
>
> In other words, the type information of its parameter isn’t lost when only specifying `D` in `E` (or another struct for that matter). The result is that the field has to be boxed to accomodate the extra type tag for dynamic dispatch.
> 
> If you check `@code_warntype f(F(D{C}(0x0)))` , you’ll also see that julia tells you about only knowing the `UnionAll` `D` and marks it red to signify that this will cause dynamic dispatch.

If I’m understanding this correctly, this means that since all of the type information must be specified to be isbits, aside from adding enough parameters for the moves and pokemon (30), I should probably go back to making the Pokemon types a field of the data type again
