# Type of function in struct

**URL:** <https://discourse.julialang.org/t/type-of-function-in-struct/61909>\
**Category:** New to Julia\
**Tags:** struct\
**Created:** [May 27, 2021, 9:16am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909 "2021-05-27T09:16:42Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 9:16am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/1 "2021-05-27T09:16:42Z")

</div>

Hello,  
I have a struct that I would like to include a function in. How should I declare its type?

```julia
Base.@kwdef mutable struct Tmp
    Δt :: Float64 = 0.3
    t :: Float64 = 0
    timestep :: Int = 0
    function = 0.0
end

```

By default it returns 0 `Float64`, but it can also return other `Float64` values. However, I believe that’s no its type. What’s the type of a function? Running `typeof` on a function doesn’t return anything.  
Thanks!

---

<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:** [May 27, 2021, 9:29am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/2 "2021-05-27T09:29:14Z")

</div>

> [@Ribeiro](#):
>
> Running `typeof` on a function doesn’t return anything.

It is a special type, that is usually printed with `typeof`. Eg

```julia
julia> typeof(sin)
typeof(sin)

```

Unless you want to be really specific, just use a type parameter, eg

```julia
struct Tmp{F}
    f::T
end

```

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 9:43am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/3 "2021-05-27T09:43:48Z")

</div>

> [@Tamas\_Papp](#):
>
> It is a special type, that is usually printed with `typeof` .

Ah, that kind of makes sense.  
Do you mean:

```julia
struct Tmp{T}
    f::T
end

```

I can’t seem to use this syntax with `@kwdef` defaults. I’d still like the function to return 0 as default.

---

<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:** [May 27, 2021, 9:51am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/4 "2021-05-27T09:51:12Z")

</div>

> [@Ribeiro](#):
>
> I’d still like the function to return 0 as default.

What about `_ -> 0.0`?

(Yes, the `F/T` is a typo).

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 10:00am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/5 "2021-05-27T10:00:26Z")

</div>

This is what I get:

```julia
Base.@kwdef mutable struct Tmp17{T}
           Δt :: Float64 = 0.3
           t :: Float64 = 0
           timestep :: Int = 0
           a :: {T} = (_ -> 0.0)
       end
ERROR: syntax: { } vector syntax is discontinued around util.jl:459
Stacktrace:
 [1] top-level scope at REPL[39]:1

```

---

<div class="post-metadata">

**Author:** ![eliascarv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eliascarv/32/22152_2.png) [@eliascarv](https://discourse.julialang.org/u/eliascarv)\
**Post date:** [May 27, 2021, 10:18am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/6 "2021-05-27T10:18:02Z")

</div>

You can use the Function type, e. g:

```julia
Base.@kwdef mutable struct Tmp1
    Δt::Float64 = 0.3
    t::Float64 = 0
    timestep::Int = 0
    function::Function = indentity
end

```

```julia-repl
julia> Tmp1().function(10)
10

```

```julia
Base.@kwdef mutable struct Tmp2
    Δt::Float64 = 0.3
    t::Float64 = 0
    timestep::Int = 0
    function::Function = (_ -> 0.0)
end

```

```julia-repl
julia> Tmp2().function()
0.0

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 27, 2021, 10:38am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/7 "2021-05-27T10:38:58Z")

</div>

Don’t call it the field `function`, that’s a Julia keyword and will cause confusion.

Also, you should avoid using abstract typing of fields, and `Function` is an abstract type. Instead, you can do

```julia
Base.@kwdef mutable struct Tmp17{T<:Function}
           Δt::Float64 = 0.3
           t::Float64 = 0
           timestep::Int = 0
           a::T = (_ -> 0.0)
       end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 27, 2021, 10:48am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/8 "2021-05-27T10:48:12Z")

</div>

BTW, `(_ -> 0.0)` is a function that takes _exactly_ one argument. If you want it to take zero arguments, you can use

```julia
() -> 0.0

```

If you want it to accept any number of arguments, including zero, use

```julia
(_...) -> 0.0

```

---

<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:** [May 27, 2021, 11:15am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/9 "2021-05-27T11:15:55Z")

</div>

> [@Ribeiro](#):
>
> ` a :: {T}`

you need `a::T`.

> [@eliascarv](#):
>
> You can use the Function type, e. g:

That has two problems:

1. it is an [abstract field type](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-abstract-container),
2. not all callables are subtypes of `Function`.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 11:22am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/10 "2021-05-27T11:22:52Z")

</div>

Thanks, but I still have an issue:

```julia
Base.@kwdef mutable struct Tmp20{T<:Function}
           Δt :: Float64 = 0.3
           t :: Float64 = 0
           timestep :: Int = 0
           a :: T = (_...) -> 0.0
       end

julia> tmp=Tmp20()
ERROR: MethodError: no method matching Tmp20(::Float64, ::Int64, ::Int64, ::var"#149#154")
Closest candidates are:
  Tmp20(::Float64, ::Float64, ::Int64, ::T) where T<:Function at REPL[43]:2
Stacktrace:
 [1] Tmp20(; Δt::Float64, t::Int64, timestep::Int64, a::Function) at .\util.jl:448
 [2] Tmp20() at .\util.jl:448
 [3] top-level scope at REPL[44]:1

```

> [@Tamas\_Papp](#):
>
> you need `a::T`

Ah, yes. Thanks.

---

<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:** [May 27, 2021, 11:52am UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/11 "2021-05-27T11:52:12Z")

</div>

The problem is

> [@Ribeiro](#):
>
> `t :: Float64 = 0`

eg use `0.0` or `::Int`.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 12:28pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/12 "2021-05-27T12:28:05Z")

</div>

Ah, thanks. That’s weird, since I’ve been using that line for a long time. I guess the `{}` stuff changed some things.  
Now the issue is the function is not modifiable.

```julia
Base.@kwdef mutable struct Tmp21{T<:Function}
    Δt :: Float64 = 0.3
    t :: Float64 = 0.0
    timestep :: Int = 0
    a :: T = (_...) -> 0.0
end
tmp=Tmp21()
tmp.a=(x->x*2)

ERROR: MethodError: Cannot `convert` an object of type var"#196#197" to an object of type var"#187#192"
Closest candidates are:
  convert(::Type{T}, ::T) where T at essentials.jl:171
Stacktrace:
 [1] setproperty!(::Tmp21{var"#187#192"}, ::Symbol, ::Function) at .\Base.jl:34
 [2] top-level scope at REPL[52]:1

```

Any ideas?

---

<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:** [May 27, 2021, 1:43pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/13 "2021-05-27T13:43:32Z")

</div>

> [@Ribeiro](#):
>
> Any ideas?

To be modifiable you need to remove the parameter (because each function has its own type) and declare that `Function`. But that will make the field abstract, and that will be bad for performance (if that matters).

One odd alternative would be (I don’t know if this would peform well, though):

```julia
julia> Base.@kwdef mutable struct A
         f::Ref = Ref(() -> 0)
       end
A

julia> a = A()
A(Base.RefValue{var"#2#4"}(var"#2#4"()))

julia> a.f[]()
0

julia> a.f = Ref(sin)
Base.RefValue{typeof(sin)}(sin)

julia> a.f[](π/2)
1.0

```

---

<div class="post-metadata">

**Author:** ![maxfreu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxfreu/32/17468_2.png) [@maxfreu](https://discourse.julialang.org/u/maxfreu)\
**Post date:** [May 27, 2021, 1:53pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/14 "2021-05-27T13:53:32Z")

</div>

If you use `Base.@kwdef`, a parametric type T, and give a default argument for the function `a`, T will be the type of the default argument. If you use an anonymous function, that type will be some random `var"#xyz"` thing (try `typeof(tmp.a)` in your last example). The point is that each function has its own type. So `sin` is of type `"typeof sin"`, same for cos and so on. In the mutable struct you have created it is no problem to change e.g. `t` to 1.0, because only the _value_ is changed. But if you want to swap out the function and you have a parametric type, where each _type_ is set in stone, you just cannot change `a` to another function, because this also changes the _type_ not the _value_. There are two ways out here: 1) fall back to `a::Function`, which might come with performance drawbacks, as the compiler won’t be able to make certain optimizations, or 2) just leave the default argument blank `a::T`. Then you can create new instances of your struct with `Tmp21(;a=sin)`, `Tmp21(;a=cos)`, so you need a new struct for each new function, but you can always change `t, timestep` etc.

Looking at the struct you want to define I assume you want to containerize the parameters for some time-dependent simulation. You can also take a step back and reconsider your code, e.g. fixed time series can nicely be expressed just with ranges `0:0.1:100`. Or you can also take a look at named tuples for initializing your code, e.g. `params = (timespan=0:0.1:10, f=sin)`.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 2:03pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/15 "2021-05-27T14:03:18Z")

</div>

@lmiq and @maxfreu  
Yes, performance is critical, so I need something that works very well. Redefining the entire struct if I need to update the function is not unreasonable. Maybe that’s what I’ll do.

Regarding taking a step back: what this function is supposed to be is a user defined body motion for my simulation. It actually would return a StaticArray with the velocity of each point in my geometry. That’s why it can’t be a simple range or something like that. I want to be able to have an input parameter which is a generic time-dependent motion (e.g. a rotation matrix or what have you). A function within the solver struct was the best I could come up with, but I’m open to opinions =].  
Thanks a lot!

---

<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:** [May 27, 2021, 2:05pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/16 "2021-05-27T14:05:21Z")

</div>

> [@Ribeiro](#):
>
> Regarding taking a step back: what this function is supposed to be is a user defined body motion for my simulation.

But the struct has to be mutable? From a user perspective this could be perfectly fine:

```julia
julia> struct A{T}
         p::Int
         f::T
       end

julia> a = A(1,sin)
A{typeof(sin)}(1, sin)

```

Why do you need mutability there?

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [May 27, 2021, 2:07pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/17 "2021-05-27T14:07:55Z")

</div>

> [@lmiq](#):
>
> Why do you need mutability there?

I made it mutable because there’s a lot of stuff in there that gets updated (e.g., current timestep). The function being mutable is nice in case I want a body to do a certain motion for n timesteps and then change that function entirely for another n timesteps. But redeclaring the struct in that case is not a bad solution. Not the most convenient, but very doable.  
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:** [May 27, 2021, 2:11pm UTC](https://discourse.julialang.org/t/type-of-function-in-struct/61909/18 "2021-05-27T14:11:51Z")

</div>

> [@Ribeiro](#):
>
> I want a body to do a certain motion for n timesteps and then change that function entirely for another n timesteps

Yeah, to do that probably it is better to redefine the whole structure when required, like:

```julia
julia> a = A(1,sin)
A{typeof(sin)}(1, sin)

julia> a = A(a.p,cos)
A{typeof(cos)}(1, cos)

```

custom constructors could make that syntax more simple, like (`a = A(a,cos)`) for multiple parameters.

But I understand your pain in wanting to keep several mutable fields inside an immutable struct. You may try `Setfield` to work with those:

```julia
julia> using Setfield

julia> @set! a.p = 2
A{typeof(cos)}(2, cos)

julia> a
A{typeof(cos)}(2, cos)

```
