# Save dispatched function for later call

**URL:** <https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218>\
**Category:** General Usage\
**Created:** [August 28, 2021, 12:51pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218 "2021-08-28T12:51:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 12:51pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/1 "2021-08-28T12:51:00Z")

</div>

Hey Julianners,  
Is it possible to save a function call like?

- “Base.+” but the dispatched version like: +(::Float32, ::Float32)

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 28, 2021, 12:59pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/2 "2021-08-28T12:59:21Z")

</div>

So you mean you want to get the specialized method object right? What’s the use of that?

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 1:08pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/3 "2021-08-28T13:08:39Z")

</div>

I am 100% sure what method will run and I don’t want the million \* million multiple dispatch to happen due to the saved “+” and other functions.

Yes the specialized method should be saved and called incredibly many amount of time. Is it possible?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 28, 2021, 1:20pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/4 "2021-08-28T13:20:34Z")

</div>

> [@Marcell\_Havlik](#):
>
> million \* million multiple dispatch

it won’t always be dynamic dispatch if that’s what you’re worrying about. you likely have an incorrect mental model on how Julia works.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 28, 2021, 1:29pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/5 "2021-08-28T13:29:23Z")

</div>

If you already know which method will run, then I guess it means that types of input are fixed. Julia will select that specialized method object automatically when compiling the method call. So you need to do nothing.

But maybe you want method object for other usages. Can you be more specific about what you want to do with these specialized method?

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 2:06pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/6 "2021-08-28T14:06:22Z")

</div>

Yeah, I can be any specific.  
I want something like this:

```julia
deref(ref::Base.RefValue{T}) where T = ref[]
deref(val) = val

ops = [+ , - , +]
out = [Ref(0), Ref(0), Ref(0)]
ins = [(2,3), (4,5), (out[1], out[2])]

for (i,op) in enumerate(ops)
	in1, in2 = deref(ins[i][1]), deref(ins[i][2])
	out[i][] = op(in1, in2)
end

```

So I want to create a sort of network of computation graph and create different optimization for this operation list and many more different research with this way.

I am afraid of it that, due to the function’s are not compilable… so “op(…)” is a little bit abstract the compilation can’t really figure out each of the [+,-,+…] functions in compilation time.  
What is so ever I specifically don’t want it to figure it out! So I want to directly specify because I don’t want the compiler or anything to have any load from dispatching to the appropriate method.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 28, 2021, 2:22pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/7 "2021-08-28T14:22:54Z")

</div>

you may find

> **[GitHub - JuliaParallel/Dagger.jl: A framework for out-of-core and parallel...](https://github.com/JuliaParallel/Dagger.jl)**
>
> A framework for out-of-core and parallel execution - GitHub - JuliaParallel/Dagger.jl: A framework for out-of-core and parallel execution

interesting because they have some sort of computation graph internally.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 2:44pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/8 "2021-08-28T14:44:38Z")

</div>

Yes, I know Dagger.jl. I want this to be different in many ways and I didn’t see how can I apply effectively Dagger.jl in my scenario, in spite of the fact that it has a scheduler which sounds really great. Also I find it very sluggish…

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 28, 2021, 2:51pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/9 "2021-08-28T14:51:59Z")

</div>

So I get it. You want some “cheap” runtime dispatches, right? You still need to perform some dispatches here, since the input types are unknown (they can be refvalue or int). But you don’t want to perform the unnecessary method table lookup (since you only want to invoke a specific method).

There are two issues here:

1. `ins` is `Vector{Any}` here, so `ins[i]` is also inferred as `Any`. You must perform a runtime dispatch in this case, since you may store any things in `ins` and they can be any types. If you only store RefValue{Int} and Int, you can type `ins` as Vector{Union{RefValue{Int},Int} instead of Vector{Any}.
2. Since you store the functions in a vector `ops`, I guess you want to type these functions, like `Int32xInt32->Int32`. Currently we have no official ways to do this, only experimental support (You can search `FunctionWrapper.jl` in github). It should “just” work for you.

But before you fix these issues, I think you just do things in a wrong way. You should not do this _ **inside** _ a language. If you want to create computation graph, you should directly work on Julia’s typed IR (or create your own IR/typed AST/Graph DSL) and perform code generation like a real compiler.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 3:37pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/10 "2021-08-28T15:37:54Z")

</div>

Yeah, indeed it was too bare example. To resolve the first issue you mention:

```julia
IN1 = Float32[2]
IN2 = Float32[3]
IN3 = Float32[7]
IN4 = Float32[5]
ops = [+ , - , +]
outs = Float32[0, 0, 0]
ins = [
  (Base.RefArray(IN1,1), Base.RefArray(IN2,1)),
  (Base.RefArray(IN3,1), Base.RefArray(IN4,1)),
  (Base.RefArray(outs,1), Base.RefArray(outs,2))
]

for (i,op) in enumerate(ops)
  outs[i] = op(ins[i][1][], ins[i][2][])
end

```

The 2. FunctionWrapper.jl sounds extremely great! I hope it really works!

Isn’t the typed AST sounds too low level for my task? For me this computation sounds very easy solution for my specific case, if it I could work with TypedFunction it would be great.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 28, 2021, 3:47pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/11 "2021-08-28T15:47:44Z")

</div>

What you’re doing right now is basically implementing a dynamically dispatched interpreter by using existing julia functionality for all those dynamic parts. Those are so loaded with lookups that a good step up would be to just generate julia code with meta programming in the first place.

If julias’ semantics aren’t useful for your interpretation of operations (which I doubt a little), writing your own language (and grammar, parser, lexer, compiler etc) to avoid dynamic dispatch (so your language would have to be strongly statically typed) would seem like the only remaining option.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 28, 2021, 4:14pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/12 "2021-08-28T16:14:10Z")

</div>

I love Julia. I don’t want a new language. I believe Julia is really extensive and it has close to no limits.  
I am just looking for a solution and as I feel it was worth to ask the question FunctionWrapper.jl looks really promising but I have to test that it really works like we believe.

---

<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:** [August 28, 2021, 6:00pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/13 "2021-08-28T18:00:06Z")

</div>

Are your actual arrays very much bigger than in your example? If not, have you considered working with tuples instead? They retain the type information of each element statically.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 29, 2021, 2:39am UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/14 "2021-08-29T02:39:24Z")

</div>

I agree with @Sukera, you are just trying to implement a interpreter (or a virtual machine) over an extremely simple arithmetic language. We can do this easily in Haskell with \< 100 line codes. If you believe this counts as a computation graph, you might just waste your time.

It’s indeed possible to twist function pointers in Julia, just like `FunctionWrappers.jl`, to achieve a more general interpreter (for arbitrary types and functions). And if you know how to do this in C/C++, then you can do this kind of low level thing in Julia (you just need to use Julia’s internal). But this is not easy and beneficial. We already have a task scheduler. You can directly spawn the computation and let Julia do it. Task indeed has some overheads and may not be appropriate if we have a lots of small computation. But if the computation is small, then we shouldn’t spawn it at all (besides, a dynamic interpreter also has some small overheads, because we need to pack and unpack parameters to execute an opcode) .

Instead, you should look at into Debugger.jl or Julia’s abstract interpreter framework. These works are much closer to what you are doing here.

PS: If you really really want to know how to get function pointers, use `which(m,tt)` to get `Method` object. The `specializations` field of `Method` stores `MethodInstance` for this call. Then the `cache` field of `MethodInstance` stores `CodeInstance`, which is just like a handle. The `specptr` field of `CodeInstance` stores the function pointer of the function. The `invoke` field also stores a pointer. The difference is that the pointer in `invoke` is a wrapper of the pointer in `specptr`. It has a signature of `void* f(void* tparams,void** args, int32 nargs)`. This signature is the same for all different functions. So you can `ccall` this function in an uniform way (there is no dispatch since the type of inputs is fixed.)

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 30, 2021, 4:54pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/15 "2021-08-30T16:54:45Z")

</div>

Yes, sorry. These are just sample data, these will be very big arrays or in some case tensors in development and production.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 30, 2021, 4:59pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/16 "2021-08-30T16:59:03Z")

</div>

I understand haskell would mean less than 100 line of codes for this specific case. But I have the our company research codebase in julia and it would be really waste of time to port everything seamlessly. Also if it is possible and fast, why would we mix languages.

Thank you for all the points I will try to check them!

Sadly FunctionWrappers.jl wasn’t enough clear for me and I coudln’t apply appropriately. ☹

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 30, 2021, 5:34pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/17 "2021-08-30T17:34:20Z")

</div>

why not take the representation you have and “compile” it to Julia expressions (ie. write a macro), and then let the Julia compiler compile that to machine code? If you “know” the types of the inputs, then you simply write the Julia expressions with type annotation.

```julia
a = 1
b = 2
foo = Expr(:call, :+, a:Int, b::Int)
eval(foo)
3

```

Instead of simple expressions you could generate functions that carry out the operations of interest.

---

<div class="post-metadata">

**Author:** ![Marcell\_Havlik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcell_havlik/32/37424_2.png) [@Marcell\_Havlik](https://discourse.julialang.org/u/Marcell_Havlik)\
**Post date:** [August 30, 2021, 6:49pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/18 "2021-08-30T18:49:49Z")

</div>

The problem here is the speed, that way is extremely inefficient.  
Eval shouldn’t be used this many time because of it is time consuming.

```julia
using BenchmarkTools

function f(ops)
  for op in ops
    eval(op)
  end
end

function g(ops, a, b)
  for op in ops
    +(a, b)
  end
end

a=2
b=3

plus = Expr(:call, :+, a::Int, b::Int)
ops=[plus, plus, plus]

@btime f($ops)
@btime g($ops, $a, $b)

```

For me it show:  
163.592 μs (99 allocations: 6.56 KiB)  
1.828 ns (0 allocations: 0 bytes)

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 30, 2021, 7:12pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/19 "2021-08-30T19:12:09Z")

</div>

> [@Marcell\_Havlik](#):
>
> Sadly FunctionWrappers.jl wasn’t enough clear for me and I coudln’t apply appropriately.

Maybe this is the important point to resolve? As far as I can tell, FunctionWrappers.jl is the exact right solution to your original problem. For example:

```julia
julia> using FunctionWrappers: FunctionWrapper

julia> ops = [+, *]
2-element Vector{Function}:
 + (generic function with 190 methods)
 * (generic function with 328 methods)

julia> wrapped_ops = [FunctionWrapper{Int, Tuple{Int, Int}}(op) for op in ops]
2-element Vector{FunctionWrapper{Int64, Tuple{Int64, Int64}}}:
 FunctionWrapper{Int64, Tuple{Int64, Int64}}(Ptr{Nothing} @0x00007fe24935fed0, Ptr{Nothing} @0x00007fe297964a78, Base.RefValue{typeof(+)}(+), typeof(+))
 FunctionWrapper{Int64, Tuple{Int64, Int64}}(Ptr{Nothing} @0x00007fe249360190, Ptr{Nothing} @0x00007fe297964a80, Base.RefValue{typeof(*)}(*), typeof(*))

julia> using BenchmarkTools

julia> @btime (for i in 1:2; z[i] = $ops[i](x, y); end) setup=(x = 1; y = 2; z = zeros(Int, 2))
  60.315 ns (0 allocations: 0 bytes)

julia> @btime (for i in 1:2; z[i] = $wrapped_ops[i](x, y); end) setup=(x = 1; y = 2; z = zeros(Int, 2))
  12.344 ns (0 allocations: 0 bytes)

```

`wrapped_ops` is a concretely-typed `Vector` of function wrappers, so we can iterate over it and called the wrapped operations much more efficiently.

If you find the `FunctionWrapper` syntax awkward, I wrote a macro here: [Can FunctionWrappers.jl express higher order functions? - #4 by rdeits](https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404/4) which might help:

```julia
wrapped_ops = [@fn((Int, Int) -> Int)(op) for op in ops]

```

or, equivalently:

```julia
wrapped_ops = @fn((Int, Int) -> Int).(ops)

```

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 30, 2021, 8:15pm UTC](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218/20 "2021-08-30T20:15:01Z")

</div>

I still don’t really understand how you’re planning to use this. If you’re planning to execute each input exactly once, then the compilation time will be unacceptable. If you’re planning to take some user input, and then do some intense calculations with it, reusing the operation over and over in a loop, then the compilation time will be less important, and the fact that the operations are fast will be advantageous.

[Next page](https://discourse.julialang.org/t/save-dispatched-function-for-later-call/67218.md?page=2)
