# Function wrapper for custom functions

Hi everyone,

I have 2 functions defined that are used for resampling a vector of reals:

``````using Distributions
using BenchmarkTools

function resampling_multinomial(weights::AbstractVector{T}, particlesN::Int) where {T<:Real}
rand(Categorical(weights), particlesN )
end

function resampling_systematic(weights::AbstractVector{T}, particlesN::Int) where {T<:Real}
#Assign cumulative Weights
uniforms = rand.( Uniform.(0, 1/particlesN) ) .+ range(0; step = 1/particlesN, length = particlesN)
path       = zeros(Int, particlesN, 1)
#Some other calculations
return path
end

resampling_multinomial( [.1, .2, .3, .4], 100) #Int64[100]
resampling_systematic( [.1, .2, .3, .4], 100) # 100*1 Array{...}
``````

Now I would like to define a wrapper function with a more suitable name and call either of the function based on a stringname from the arguments.

``````#Wrapper function for my custom functions
resample(weights::AbstractVector{T}, particlesN::Int, method::String = "multinomial") where {T<:Real} = resampling_multinomial(weights, particlesN)
resample(weights::AbstractVector{T}, particlesN::Int, method::String = "systematic") where {T<:Real} = resampling_systematic(weights, particlesN)
#Default method
resample(weights, particlesN) = resample(weights, particlesN; method = "systematic")

#NOT working
resample( [.1, .2, .3, .4], 100, "multinomial") # NOT CORRECT - 100*1 Array instead of Int64[100]
resample( [.1, .2, .3, .4], 100, "systematic") # 100*1 Array
resample( [.1, .2, .3, .4], 100) # 100*1 Array
``````

Unfortunately, this is not working. I cannot dispatch the functions cause the two functions do not differentiate in any type. If I try it the way I did above the function wrapper just gets overwritten and will always use the last line of code.
QUESTION: How can I define a more convenient function name and call either of my custom resampling functions based on a stringname from the arguments?

Best regards,

Why not a simple branch:

``````function resample(weights, particlesN; method = "systematic")
if method == "systematic"
resampling_systematic(...)
else
resampling_multinomial(...)
end
``````

I suppose if you really wanted to dispatch at compile time you could define `struct Systematic end` and `struct Multinomial end` and define wrappers of the form

``````function resample(weights, particlesN, method :: Systematic)
resampling_systematic(...)
end
``````
1 Like

Thank you! I think the second suggestion is the way to go for me. I did not really want to branch it as these functions will be called many times in other functions.

Iām just wondering: can the compiler infer the type of `method` while the programmer cannot?

I would check `@code_warntype` on this code if performance is important.

It seems to be able to, `@code_warntype` gives the following output for the problem above:

``````Body::Array{Int64,2}
1 ā %1 = invoke Main.resampling_systematic(_2::Array{Float64,1}, _3::Int64)::Array{Int64,2}
āāā      return %1
``````

I still need to call `Multinomial()` and `Systematic()` instead of `Multinomial` and `Systematic` in the function wrapper as the latter are no structs but apart from that it is perfect.

I was suggesting to make up `struct`s that work rather like an `enum`. That is, define

``````struct Systematic end
``````

so that you can dispatch on the function signature by passing an object of type `Systematic`.