Type instability if function inside a struct is run inside another function

Hello,

If I have a function inside a struct and run that function inside another function, the output will be type-unstable.

Example:

struct StructWithFunction
    func::Function
end
struct_with_function = StructWithFunction(+)
@inferred struct_with_function.func(2,3)
function test(struct_with_function)
    struct_with_function.func(2,3)
end
@code_warntype test(struct_with_function)

Output is

5

Variables:
  #self# <optimized out>
  struct_with_function::StructWithFunction

Body:
  begin 
      return ((Core.getfield)(struct_with_function::StructWithFunction, :func)::F)(2, 3)::Any
  end::Any

This is tested with Julia v0.6.4

Anything I can do about it?

struct StructWithFunction{F<:Function}
    func::F
end
6 Likes

As a side note, Function is an abstract type and as other abstract types they are usually slow as direct field types.

As an interesting side note we’ve recently lost the ability to efficiently unbox functions from containers as currently FunctionWrappers.jl is required for that and it only works on 0.6. I’d be interested to know if functors of some kind would be efficient as a temporary work around.

There’s a PR to fix FunctionWrappers.jl pending, but it’s been stalled waiting for code review for about 3 weeks: Fixes for Julia 0.7. Drop 0.5 and 0.6. by tkoolen · Pull Request #7 · yuyichao/FunctionWrappers.jl · GitHub

1 Like

Yay! :tada: At this point I’m just glad it’s there because honestly I had absolutely no clue how to do it myself. I checked to see if there were any in the past but I guess not recently. It’s scary not to at least have that functionality in a functional language like Julia. I don’t use it that often but when I do it doesn’t seem like there are many alternatives.

It works on the linux nightlies, that’s all I need :smile:

(As a fun example of where there seemed to be no good alternatives see my MOS 6502 simulator.)