# Adding methods to a function wrapper dynamically

**URL:** <https://discourse.julialang.org/t/adding-methods-to-a-function-wrapper-dynamically/10111>\
**Category:** General Usage\
**Created:** [April 2, 2018, 12:21am UTC](https://discourse.julialang.org/t/adding-methods-to-a-function-wrapper-dynamically/10111 "2018-04-02T00:21:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [April 2, 2018, 12:21am UTC](https://discourse.julialang.org/t/adding-methods-to-a-function-wrapper-dynamically/10111/1 "2018-04-02T00:21:38Z")

</div>

Good morning from Manila! 👋☕

I have a function wrapper:

```julia
julia> struct fwrap
   f::Function
end

julia> fw = fwrap(() -> nothing)
fwrap(#11)

```

I can now implement multiple methods for my `f`, e.g.

```julia
julia> fw.f(x) = x^2

julia> fw.f(s::String) = s*s*s

```

Now, I want to dynamically add methods based on arguments that are not known ahead of time. For example, I might be given an array of types `[T1, T2, T3]` and another function `h` and I want to add a method

```julia
fw.f(::T1,::T2,::T3) = h

```

Any ideas how I can do this (preferably without using `@eval`)?

For reference to the actual issue, please see this [https://github.com/JuliaWeb/HTTP.jl/issues/226](https://github.com/JuliaWeb/HTTP.jl/issues/226)

Thanks 🙏

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 2, 2018, 7:43pm UTC](https://discourse.julialang.org/t/adding-methods-to-a-function-wrapper-dynamically/10111/2 "2018-04-02T19:43:44Z")

</div>

So do you want a fallback that returns the function object `h` for any set of argument types for which you haven’t created a more specific method? If that’s the case,

```julia
fw.f(args...) = h

```

would work. But maybe you could explain a little bit more about what you’re trying to accomplish (wasn’t straightforward to gather from the issue you linked); it could be that I don’t understand the problem, or that there’s a different approach that is more appropriate.

As a side note, having `f` as an abstractly typed field in `fwrap` (`Function` is an abstract type) means that all dispatch will happen at runtime, which is bad for performance.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [April 3, 2018, 8:52am UTC](https://discourse.julialang.org/t/adding-methods-to-a-function-wrapper-dynamically/10111/3 "2018-04-03T08:52:11Z")

</div>

I’m pretty sure that in general you’ll need `eval`; the only way I know to add methods is by “coding” them.

Without having read the linked issue, maybe this could help:  
If performance is not paramount (you should profile) or if JIT-time is an issue, then you could hand-code the dispatch:

```julia
struct Fwrap
  disp::Dict{Type,Function}
end
Fwrap() = Fwrap(Dict{Type,Function}())
(fw::Fwrap)(args...) = fw.disp[typeof(args)](args...) # make Fwrap callable
register_method(typs, fw::Fwrap, fn) = fw.disp[typs] = fn

# use it:
fw = Fwrap()
register_method(Tuple{Int}, fw, sin)
fw(5)==sin(5)
register_method(Tuple{Float64}, fw, cos)
fw(5.0)==cos(5)

```
