Trying to understand parametric args in functions

I have looked at the docs for parametric args in functions and cannot understand how to apply it to what I want to program.

I have a function function ga(s::String,g::T) where ::T can be a ::String or a ::Array{Num} and have an if statement in ga that does on thing for ::String and another for ::Array{Num}. Because there is a lot of common code for each case I don’t want to define two functions (in the g::String case I have code to convert g::String to g::Array{Num}) -

function ga(s::String,g::String)

function ga(s::String,g::Array{Num})

Is there a way I can do this with parametric arguments (multiple dispatch)? Thank you for any help you can give me.

Because there is a lot of common code for each case I don’t want to define two functions

You don’t have to, you can dispatch somewhere in the function, too.

function ga(s::String, g)
   g = make_array(g)
   # other code
end

make_array(g::Array{Num}) = g
make_array(g::String) = [1, 2, 3]

In terms of compilation latency, it’s best to do all conversions towards the unified format first, then dispatch to the “real” function doing all the work. Then that one will not be compiled again and again.

Thank you. I thought of something similar after writing my question -

function ga(a::String,g::String)
    g = make_array(g)
    return ga(a::String,g::Array{Num})
end```

You could also declare a Union.

const G = Union{String, Array{Num}}

function ga(s::String,g::G)
...
end

# alternatively, to specialize on a type

function ga(s::String, g::T) where T <: G
...
end

If I’m not mistaken there is no difference in the specialization of those two alternatives. Both will specialize to the given concrete type.

What I meant is if you wanted to do something with the type parameter, T.

1 Like

I tend to dispatch this way, especially …

function f(a, b, c)
    # main computation
end
f(inputs::NamedTuple) = f(inputs.a, inputs.b, inputs.c)

Is there a performance reason to dispatch on a smaller internal function instead?

The last paragraph here seems to state the opposite of what you are showing in the code?

I guess my question is more succinctly which method is better to define?

make_array(g::Array{Num}) = g
# or 
ga(a::String, g::String) = ga(a, make_array(g))

The latter seems more intuitive to me.

Yes I was trying to say don’t necessarily do it like this :slight_smile:

1 Like

Yeah get conversion out of the way as early as possible

1 Like