# Calculations in type parameters without pure

**URL:** https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106
**Category:** General Usage
**Tags:** question
**Created:** [July 22, 2021, 1:32pm UTC](https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106 "2021-07-22T13:32:24Z")
**Posts on this page:** 4
**Page:** 1

<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: [July 22, 2021, 1:32pm UTC](https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106/1 "2021-07-22T13:32:24Z")

</div>

Suppose I have a type parameter `M`, which is a deterministic function of another parameter `N`. I would like to save it in the type, but not sure how to make this type stable _without_ `@pure`. Is that even possible? MWE:

```julia
@inline calcM(x) = 2^x

struct MyType{N,M} end

function MyType{N}() where N
    @assert N ≥ 0
    M = calcM(N)
    MyType{N,M}()
end

@code_warntype MyType{3}() # not inferred of course

```

---

<div class="post-metadata">

### Author: ![JonasIsensee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasisensee/32/4704_2.png) [@JonasIsensee](https://discourse.julialang.org/u/JonasIsensee)
#### Post date: [July 22, 2021, 1:43pm UTC](https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106/2 "2021-07-22T13:43:34Z")

</div>

I don’t have an answer to this, but this is definitely not an `of course`.  
If you just simplify the function to e.g.

```julia
@inline calcM(x) = x^2

```

then compiler decides to evaluate it during compile time:

```julia
julia> @code_warntype MyType{3}()
Variables
  #self#::Type{MyType{3, M} where M}
  M::Int64

Body::MyType{3, 9}
1 ─ Core.NewvarNode(:(M))
│ %2 = ($(Expr(:static_parameter, 1)) ≥ 0)::Core.Const(true)
│ %2
└── goto #3
2 ─ Core.Const(:(Base.AssertionError("N ≥ 0")))
└── Core.Const(:(Base.throw(%5)))
3 ┄ (M = Main.calcM($(Expr(:static_parameter, 1))))
│ %8 = Core.apply_type(Main.MyType, $(Expr(:static_parameter, 1)), M::Core.Const(9))::Core.Const(MyType{3, 9})
│ %9 = (%8)()::Core.Const(MyType{3, 9}())
└── return %9

```

Along those lines: You can nudge the compiler to make your example type stable by adding an additional type check.

```julia
julia> function MyType{N}() where N
           @assert N ≥ 0
           T = typeof(N)
           M = calcM(N)::T
           MyType{N,M}()
       end

julia> @code_warntype MyType{3}()
Variables
  #self#::Type{MyType{3, M} where M}
  M::Int64
  T::Type{Int64}

Body::MyType{3, 9}
1 ─ Core.NewvarNode(:(M))
│ Core.NewvarNode(:(T))
│ %3 = ($(Expr(:static_parameter, 1)) ≥ 0)::Core.Const(true)
│ %3
└── goto #3
2 ─ Core.Const(:(Base.AssertionError("N ≥ 0")))
└── Core.Const(:(Base.throw(%6)))
3 ┄ (T = Main.typeof($(Expr(:static_parameter, 1))))
│ %9 = Main.calcM($(Expr(:static_parameter, 1)))::Core.Const(9)
│ (M = Core.typeassert(%9, T::Core.Const(Int64)))
│ %11 = Core.apply_type(Main.MyType, $(Expr(:static_parameter, 1)), M::Core.Const(9))::Core.Const(MyType{3, 9})
│ %12 = (%11)()::Core.Const(MyType{3, 9}())
└── return %12

```

---

<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: [July 22, 2021, 1:54pm UTC](https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106/3 "2021-07-22T13:54:40Z")

</div>

Thanks,

```julia
@inline calcM(x) = 1 << x

```

also works.

I am just not sure what the rules are. Is it because `2^x` goes to `power_by_squaring`, which is recursive?

---

<div class="post-metadata">

### Author: ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)
#### Post date: [July 22, 2021, 3:15pm UTC](https://discourse.julialang.org/t/calculations-in-type-parameters-without-pure/65106/4 "2021-07-22T15:15:30Z")

</div>

I could be wrong here, but isn’t this a good use case for generated functions?

```julia
@generated function MyType{N}() where N
  M = calcM(N)
  return quote
    MyType{N,$M}()
  end
end

```

seems to work okay with inference.
