# Struct with a field of type \`Function\`

**URL:** <https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669>\
**Category:** Performance\
**Tags:** question\
**Created:** [November 6, 2020, 8:02am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669 "2020-11-06T08:02:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Azzaare](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azzaare/32/21008_2.png) [@Azzaare](https://discourse.julialang.org/u/Azzaare)\
**Post date:** [November 6, 2020, 8:02am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/1 "2020-11-06T08:02:45Z")

</div>

Hi there,

I am trying to define a struct that contains the keys to a set of variables `vars` and a function with a signature that corresponds to those variables.

```julia
struct MyType
    f::Function
    vars::Vector{Int}
end

```

A few things concern me about how to optimize this struct and constrain the function signature.  
Is there a way to constrain the signature of `f`? I would be so happy to be able to something such as:

```julia
struct MyType{T<:Real}
    f::Function{x::T...}
    vars::Vector{Int}
end

```

I know that `Function` is an abstract type, and basically, I would like to ensure that at least a method of `f` has the correct signature.

Outside the signature matter (that can be ignored in the worst case), is there an optimal way to store a function in a struct?

---

<div class="post-metadata">

**Author:** ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)\
**Post date:** [November 6, 2020, 8:19am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/2 "2020-11-06T08:19:57Z")

</div>

I’d probably do something like this

```julia
struct MyType{F<:Function, A}
    f::F
    vars::A
    function MyType{F,A}(f, vars) where {F<:Function,A}
        applicable(f, vars...) || throw(ArgumentError("Function has no method with signature $(typeof.(vars))"))
        return new(f, vars)
    end
end

MyType(f::F, vars::A) where {F<:Function,A} = MyType{F,A}(f, vars)

```

EDIT: This makes all fields concrete, and implements a check that the variables `vars...` are a valid signature of some method of `f` (I assume that’s what you’re asking?)

---

<div class="post-metadata">

**Author:** ![tisztamo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tisztamo/32/16200_2.png) [@tisztamo](https://discourse.julialang.org/u/tisztamo)\
**Post date:** [November 6, 2020, 8:23am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/3 "2020-11-06T08:23:46Z")

</div>

Parametrizing the struct with the type of the function itself will give you fast calls. If you call the function several times, this may be good overall for performance.

For checking the signature the only way I know of is to check it in the constructor with `methods()`. That has the drawback of checking at struct creation, not at the call.

EDIT: too late. 🙂

---

<div class="post-metadata">

**Author:** ![Azzaare](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azzaare/32/21008_2.png) [@Azzaare](https://discourse.julialang.org/u/Azzaare)\
**Post date:** [November 6, 2020, 8:42am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/4 "2020-11-06T08:42:25Z")

</div>

Both of you, thank you. That looks pretty neat. 🙇‍♂️

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 6, 2020, 1:28pm UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/5 "2020-11-06T13:28:18Z")

</div>

Please note that, as with any parametric data type, any function you create that take a `MyType{F, A}` will probably be recompiled and specialized for each call with `MyType` of a different `F` and `A`. You may want to check in your use case how the extra specializations triggered by `MyType{F, A}` compare to the lack of specializations of just `MyType` (i.e., if the overhead is worth it). Or go by a third path an keep using `MyType{F, A}` but annotate some method parameters with `@nospecialize`.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [November 6, 2020, 1:49pm UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/6 "2020-11-06T13:49:23Z")

</div>

Functions are first class objects in Julia, so it might make more sense to use a closure, a higher-order function, or a [callable struct](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects), depending on your use case. Can you elaborate on why you need a function stored in a struct?

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [November 6, 2020, 2:10pm UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/7 "2020-11-06T14:10:48Z")

</div>

If you need to be able to make concrete collections of your type while having each struct containing different functions and being type stable, you may want to look into FunctionWrappers.jl

[https://github.com/yuyichao/FunctionWrappers.jl](https://github.com/yuyichao/FunctionWrappers.jl)

---

<div class="post-metadata">

**Author:** ![Azzaare](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azzaare/32/21008_2.png) [@Azzaare](https://discourse.julialang.org/u/Azzaare)\
**Post date:** [November 10, 2020, 7:12am UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/8 "2020-11-10T07:12:52Z")

</div>

I am writing a solver with variables and constraints (predicates over the variables) given by the user.  
Those constraints are scalable predicates over a vector/tuple of variables.

Ideally, I want the user to have a comprehensible error on the signature type of each predicate in case the signature is incorrect. And I would prefer it to be checked within the Constraint constructor.

However, I am opened to any suggestions. I mainly focus on having a working and user-friendly solver at the moment, and I will focus on efficiency after that.

---

<div class="post-metadata">

**Author:** ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)\
**Post date:** [November 10, 2020, 4:33pm UTC](https://discourse.julialang.org/t/struct-with-a-field-of-type-function/49669/9 "2020-11-10T16:33:26Z")

</div>

If your predicates are not completely arbitrary but can instead be parametrized in some way, you might want to consider wrapping the parameters in a callable type instead of wrapping a function. So if your constraints are, e.g. all of the form `min[i] <= r[i] <= max[i]`, something like

```julia
struct Constraint{N,T}
    min::NTuple{N,T}
    max::NTuple{N,T}
end

(c::Constraint{N})(r::NTuple{N}) where {N} = all(c.min .<= r .<= c.max)

```

would save you needing a new function `f(min, max) = all(r -> min .<= r .<= max)` of different type for different values of `min` and `max`. I don’t know if this is of any use in your case. I only mention because I recently had this situation and this approach allowed me to remove all allocations that were killing my performance. FunctionWrappers is another interesting approach that is even more general, as @WschW says.
