Copying a question from Zulip given that it may be useful in general to discuss in Discourse…
A good trick to perform algebraic operations with both arrays and numbers generically is to use LinearAlgebra.I instead of 1:
julia> f(x) = x*I
f (generic function with 1 method)
julia> f(1)
UniformScaling{Int64}
1*I
julia> f(ones(3,3))
3×3 Array{Float64,2}:
1.0 1.0 1.0
1.0 1.0 1.0
1.0 1.0 1.0
The problem I have is that the function f is used a lot with simple numbers, and the return type of f(1) is not a Number. How do we get around this issue? Is there a function in Base that converts a UniformScaling with a single entry to a simple Number?
If I can provide a simple number in most cases, I will have less issues downstream, and the compiler will likely perform more low-level optimizations?
I know that a UniformScaling object a with a single entry has the field a.λ with the actual number it represents. I wonder how to retrieve this number elegantly, possibly without performance penalties.
How to create a method that works with arrays too? In other words how to dispatch on different kinds of UniformScaling and retrieve the underlying array vs. number?
Because most packages out there fall into this Julia anti-pattern where the code constrains the type of functions to numbers, e.g. f(x::Number) = ... prematurely. Also, I am assuming that the compiler can do more magic with the raw numbers in general compared to a more complicated struct.