# Is it good to include a function in my struct?

**URL:** <https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129>\
**Category:** Performance\
**Created:** [February 24, 2023, 12:18pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129 "2023-02-24T12:18:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [February 24, 2023, 12:18pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/1 "2023-02-24T12:18:41Z")

</div>

I have a struct which has a field referring to a function, which is used as following.

```julia
struct myT
f::Function
end

function Base.getindex(foo::myT, i)::Float64
    foo.f(...)
end 

```

I noticed that `code_warntype` shows

```julia
│ %50 = Base.getproperty(ts, :fn)::Function
│ %51 = (%50)(p)::Any
│ %52 = Base.getproperty(ts, :fval)::Dict{NTuple{15, Int64}, Float64}
│ Base.setindex!(%52, %51, I)
│ %54 = Base.convert(%3, %51)::Any
│ %55 = Core.typeassert(%54, %3)::Float64

```

There are a few `Any`. I don’t know if this means the compiler cannot determine the return type of the function `f` in compile time. I added `Float64` as the return type, but it seems only to do a type conversion at the end, and does not tell the compiler the information of the function.

I’m curious if this would affect the performance. Thanks.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 24, 2023, 12:20pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/2 "2023-02-24T12:20:08Z")

</div>

`Function` is an abstract type. Each function has its own type. If you want your struct to contain a function, for performance reasons use a type parameter:

```julia
struct myT{F<:Function}
    f::F
end

```

---

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [February 24, 2023, 3:42pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/3 "2023-02-24T15:42:16Z")

</div>

Thank you. I have a related question. I have another type which depends on the parametric type `myT{...}`.

```julia
Struct SMat{valT}
   t::myT
   
   val::valT
   function SMat(t::myT{valT, ....}, ....) where valT
       new{valT}(t, val)
   end
end

```

The above type can get the parameter of `myT`, but I also want `myT` to be concrete. I tried several ways but all failed.

Is there a clear introduction to julia’s template system? I feel very confused.

Thank you.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 24, 2023, 4:10pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/4 "2023-02-24T16:10:00Z")

</div>

There are two options, either you parameterize the parameter of the inner struct:

```julia
struct SMat{valT,F<:Function}
    t::myT{F}
    val::valT
end

```

or, if that starts to become too complicated, you can parameterize the whole field

```julia
struct SMat{valT, T<:myT}
    t::T
    val::valT
end

```

---

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [February 24, 2023, 6:18pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/5 "2023-02-24T18:18:23Z")

</div>

I think I would like to go with the 2nd approach, but the issue is that the type `valT` should be inferred from the type of `t`, which is `myT{valT, ...}`. If I parametrize the whole field, that information seems hidden. Of course I can provide it explicitly, but I’m curious if I can make the compiler infer this information.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 24, 2023, 6:20pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/6 "2023-02-24T18:20:53Z")

</div>

I’m not sure if I understand, but if `valT` has the same type of `t` you can use

```julia
struct SMat{T<:myT}
    t::T
    val::T
end

```

of if it shares some type parameter with t, you could use

```julia
struct SMat{valT, T}
    t::T{ValT}
    val::valT
end

```

---

<div class="post-metadata">

**Author:** ![linwaytin](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@linwaytin](https://discourse.julialang.org/u/linwaytin)\
**Post date:** [February 24, 2023, 8:32pm UTC](https://discourse.julialang.org/t/is-it-good-to-include-a-function-in-my-struct/95129/7 "2023-02-24T20:32:04Z")

</div>

The type of `t` is quite complicated. Maybe I didn’t design it well at the beginning. I decided to specify `valT` directly to `SMat`.

Thanks a lot for your help!
