Your second definition replaces the first (the names don’t matter, only the types so here in both cases you have “4 generic arguments”).
Here are some possibilities:
-
Users can give
nothingforJacobF:# method 1 FDEsolver(F, tSpan, y0, β, ::Nothing, par...) # method 2 FDEsolver(F, tSpan, y0, β, JacobF, par...)then users can write
FDEsolver(F, tSpan, y0, β, nothing, ...)to get the first method. -
Make the second method more specific by giving a type for
JacobF, for example:# method 1 FDEsolver(F, tSpan, y0, β, par...) # method 2 FDEsolver(F, tSpan, y0, β, JacobF::AbstractMatrix{<:Real}, par...)This works if the first
parargument never has the same type asJacobF: then Julia can use the type of the 5th argument to decide which method to call. -
Get rid of the vararg. What are these parameters? maybe there’s a better way to pass them than using a vararg?
-
Pass
JacobFas an optional keyword argument:FDEsolver(F, tSpan, y0, β, par...; JacobF=nothing)Then in the definition of
FDEsolveryou can doif isnothing(JacobF) .... Or you can dispatch on its value like in option 1, but hidden from the user:# method 1 and 2 FDEsolver(F, tSpan, y0, β, par...; JacobF=nothing) = _FDEsolver(F, tSpan, y0, β, JacobF, par...) # unexported methods _FDEsolver(F, tSpan, y0, β, ::Nothing, par...) = ... _FDEsolver(F, tSpan, y0, β, JacobF, par...) = ...