Design advice

Hi,

I would like to hear some design advice. I want the user to pass two parameters to a function where the second parameter depends on the first one. However, for pratical reason, I dont want the user to write a complicated call. Hence, the actual call is like:


struct Algo{T}
    a::T
end

# the way that works
function solve(a = 1.0; options = Algo(a))
    # the solve function 
    @show options.a
end

whereas I would like it to be

solve(a = 1.0; options = Algo())

but Algo() is not defined. Has anyone encountered such question? What have you done?
Thank you for your suggestions,

Best regards,

I don’t understand the question: you want options to depend on a, but implement it in a way that doesn’t?

I would go with something like

default_options(a) = A(a) # can customize it later

function solve(a = 1.0; options = default_options(a))
    @show options
end

then document and expose default_options as part of the API, so if the user wants to customize things the whole thing is clean and transparent.

I wrote A(a) instead of A().

I know it sounds reasonable (altough less if you think that a is a struct with 10 fields and Algo depends on one of those fields), this is what I proposed. But is seems clunky (he has to pass a twice) to me as the user has to know the internals of A.

Something like

const default_option = ...

function solve(a = 1.0; options = default_option)
     options = Algo(a, options)
end

or something then?

You can do whatever you want in Algo then and the user only passes in the one field.

Not sure. My MWE seems too minimal. There are many algorithm (aka struct) the user can pass. There is Algo1, Algo2…

My problem originates from my package where I want the user to pass a linearsolver (ie a in the above MWE) and also a Bordered linear solver (ie Algo1, Algo2… above) which depends on the linear solver passed by the user. But somehow, I was wondering how to make the user pass the linearalgo only once to solve.

Right now, in package, the linear bordered solver is pass with a Symbol. I would like to remove this and all the if in here.

This seems to be the crux and is the cause of the repeating. You have a both by itself and also shoved in another object. That seems unnecessary. Couldn’t it be something like

function solve(solver = LinearSolver();  options = Algorithm())
     create_final_object(solver, options)
end

That is, the Algorithm() object doesn’t need to know about solver. But inside the body of the function you are free to mix these however you want.

1 Like

Yes I like it! Thank you.