Which is prefered design of an API - dispatching on Type
or dispatching on type of argument?
Consider the simple code below
abstract type Ab end
struct B <: Ab end
struct C <: Ab end
f(x::Int,::Type{B}) = "I am B and got $x"
f(x::Int,::Type{C}) = "I am C and got $x"
f_main(x_plus2::Int,T::Type{U}) where U <: Ab = f(x_plus2-2,T)
g(x::Int,::B) = "I am B and got $x"
g(x::Int,::C) = "I am C and got $x"
g_main(x_plus2::Int,t::U) where U <: Ab = g(x_plus2-2,t)
@assert f_main(8,B) == g_main(8, B())
@assert f_main(8,C) == g_main(8, C())
Which API you would consider better - f
or g
?
One advantage of g
is that additional parameters could be added via B
and C
constructors (after adding fields them to struct
) and hence is quite popular around.
On the other hand f
requires less typing by the user of the API and sometimes you know that that one will not need to use g
s functionality.
Which feels better?