You can actually do this with no language changes if you’re willing to write (A)⁻¹
rather than A⁻¹
. Here’s an example at the REPL:
julia> begin
struct Inverter end
const ⁻¹ = Inverter()
Base.:(*)(A, ::Inverter) = inv(A)
end
julia> A = rand(3,3)
3×3 Array{Float64,2}:
0.51549 0.0616877 0.530502
0.783366 0.0598045 0.697045
0.381722 0.833891 0.632847
julia> (A)⁻¹
3×3 Array{Float64,2}:
-13.5368 10.0475 0.280811
-5.72129 3.08199 1.4014
15.704 -10.1216 -0.435822
julia> ((A)⁻¹)*A ≈ I(3)
true
This works because (a)b
is parsed as a * b
:
julia> quote (a)b end
quote
#= REPL[7]:1 =#
a * b
end
so we need only define an object ⁻¹
which when multiplied by A
on the left produces inv(A)
, trivially easy with multiple dispatch.
One could do the same with ²
to make an squaring operator if they were unable to stomach reading x^2
or x*x