API for specifying which version of a function to use in a package

In IntervalArithmetic.jl we need a way to choose between different versions of a function (e.g. the power function) that have different performance / accuracy tradeoffs.

Is there a standard way to have an API for that? Maybe something along the lines of

abstract type APIChoice end
abstract type PowerAPIChoice <: APIChoice end

struct AccuratePowers <: PowerAPIChoice end
struct FastPowers <: PowerAPIChoice end

IntervalArithmetic.specify!(AccuratePowers())
IntervalArithmetic.specify!(FastPowers())

The implementation would be, for the moment, to redefine all the corresponding functions appropriately. Strictly speaking this should be some kind of contextual dispatch, however.

1 Like

“contextual dispatch” sounds like “trait-based dispatch” where the trait selects over chosen-behavior appropriate algorithms rather than utilized-data-type appropriate algorithms.

Yes pretty much. It’s a phrase that I learnt from the Cassette.jl world.

Basically you want to do a whole calculation inside a scope where you choose “accurate powers” or “fast powers”. For e.g. testing you may want to be able to run in either of those two situations and record the respective results and compare them.

Maybe the @dynamo macro from IRTools.jl could be useful?

1 Like

That seems very much overkill?

In C++ you can give something called “execution policy” to algorithms (https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t). These are unique types just passed in as an argument to the algorithm. This is pretty much exactly the same as what you proposed in the first post and seems like a good idea to me.

2 Likes

I use to dispatch on procedures which make sense for a given data type and chosen method quite often

function solve(method, data)
     data = step1(method, data)
     data = step2(method, data)
     return data
end

solve(MyMethod(arg=true), mydata)

Isn’t that just multiple dispatch in practice?

3 Likes