Could you give an example of what you are doing where the older style of overloading `op`/`op!` allows more code reuse? Perhaps we can give you some pointers for how to use it in a better way. For example, the initial example you showed could be rewritten more simply by overloading `op!` with:
# This makes it so you can overload without writing `ITensors.op!`
import ITensors: op!
function op!(Op::ITensor, ::OpName"A", ::SiteType"MySite", s::Index)
Op[s' => 1, s => 2] = A12
end
function op!(Op::ITensor, ::OpName"B", ::SiteType"MySite", s::Index)
Op[s' => 1, s => 3] = B12
end
which I think is pretty minimal code (and like Miles said, in general we have found this style to be a lot cleaner and easier to maintain compared to the older style where you need a long list of `if ... elseif ...` statements). If you have a common operation you are performing across multiple operators, you could include a helper function:
function mysite_op_helper!(Op::ITensor, s::Index)
# Perform some common operation that works for multiple op definitions
Op[s' => 1, s => 1] = sqrt(2)
end
function op!(Op::ITensor, ::OpName"A", ::SiteType"MySite", s::Index)
mysite_op_helper!(Op, s)
Op[s' => 1, s => 2] = A12
end
function op!(Op::ITensor, ::OpName"B", ::SiteType"MySite", s::Index)
mysite_op_helper!(Op, s)
Op[s' => 1, s => 3] = B12
end
This example is a bit contrived, but I think it helps illustrate the added flexibility of working with function overloads.