OK I know my title doesn’t help but I don’t know how to explain my problem in a better way.
Here is the thing, I have a function fn1 that is called by another function fn2, and the dispatch is made on the type of the first argument in fn2 that is a subtype of a custom abstract type (“MyAbstractType”).
I want to implement different methods for fn1 in my package, possibly with different arguments, and some are computed in fn2 before calling fn1. The user could also implement its own method for fn1.
Here is the code of my abstract type for dispatch:
abstract type MyAbstractType end
Here is fn2:
function fn2(x1,x2::MyAbstractType)
a = rand(1) + x1
b = fn1(x2)
return (b + a)
end
Here is one method for fn1:
struct Myfn1Struct <: MyAbstractType
g::T
end
function fn1(x2::Myfn1Struct)
x2.g+ rand(1)
end
OK now my issue is that I want fn1 methods to take any king of parameter (after x2) that is available from fn2 (fn2 computes a lot of variables, not just “a”). For example one could implement this method (adding the “a” parameter):
struct Myfn1Struct2 <: MyAbstractType
g::T
end
function fn1(x2::Myfn1Struct2, a)
x2 .g + rand(1) * a
end
The thing is this implementation of fn1 is not compatible with how we call it from fn2 anymore. fn1 is called like this in fn2:
b = fn1(x2)
But should be called like this when x2::Myfn1Struct2 :
b = fn1(x2,a)
How can I make the call more generic ?
I thought about adding all variables from fn2 that could be used by fn1 as arguments to fn1 so I can use the same call, and dispatch on the first argument, but I find it ugly.
I also thought about adding the variables computed in fn2 to a common struct that would be passed to fn1, but I feel passing that much information to a simple function is over-killed. Especially because I also need performance (those functions are called millions of times).
I could also implement several fn2 and dispatch on the call to fn2 considering the type of x2. But fn2 is complicated and has a lot of code, so it doesn’t feel right to copy paste a lot of this code.
Also I know I could break fn2 into several functions, but it represents a whole concept on its own and I want it to be easy to understand when reading it (it is already complicated enough as it is, I don’t want the reader to jump back and forth between functions).