Well, after some considerations, it looks like there is a third option. If it is known beforehand, that values are of little interest, and they should be processed to get some result, we can just do it in place.
function solve3(f, poly)
a, b, c = poly
if a == 0
if b == 0
return f(NoRoots()) # It should be infinity but 4 types is more than enough already
else
return f(SingleLinearRoot(-c/b))
end
end
D = b^2 - 4*a*c
if D < 0
return f(NoRoots())
elseif D == 0
return f(SingleRoot(-b/(2*a)))
else
sD = sqrt(D)
return f(TwoRoots((-b + sD)/(2*a), (-b - sD)/(2*a)))
end
end
This small change uses multiple dispatch system without abusing it (I guess?). And it is even faster than flag system, probably because Julia can inline functions and optimize resulting code.
julia> @btime sum(x -> solve3(cnt, x), $polynomials)
1.554 μs (0 allocations: 0 bytes)
I can’t see any problems with this approach. Am I wrong or it is an idiomatic approach to this issue?