Remove type piracy
The matrix multiplication here should likely be implemented with an MKLSparse.matmul or something instead of type piracying the Base matrix multiplication with more specific versions.
There is something to be said in favor of the current type piracy approach. If a package uses the LinearAlgebra mul! API, and a user wants to make use of MKL for such package, it is enough that the user does using MKLSparse. If we remove this type piracy, that becomes impossible, and the package needs to provide a mechanism to switch to MKL.
Yeah, that's true. An alternative would be for the sparse matrix multiplication API to let you set a "backend" that does the computation. Basically, separate the concept of sparse matrix multiplication from the implementation that currently is in Base.
But even in that case, the package would still need to expose the mul! backend as part of its API in some way. In fact, I see this instance of type piracy as the one situation where type piracy is desirable. One usually warns against type piracy because it can change behavior without warning through inter-package interactions. In this case we actually want the "without warning" part. The behavior, however, is not changed, only the performance (by a substantial amount if using multithreading). The idea of MKLSparse is precisely this, hijack the Julia internals to make sparse linalg faster without changing anything else. And I see nothing wrong about that in this case...
In fact, I see this instance of type piracy as the one situation where type piracy is desirable
Well, what happens if there is another package that provides sparse matrix multiplication using some other backend? And what happens when both those packages happen to be loaded?
If both packages implement the same behaviour, the result is the same, only performance changes. But I do get your point. The idiomatic Julian approach would be to have the user wrap whatever input in a new type owned by MKLSparse, and have the MKLSparse mul! dispatch on that type. Of course the package receiving the input in question would need to be fully generic, etc. So what should be done here? I fear that MKLSparse would become much less useful by making it more correct...
Perhaps there could be a macro? E.g. A * b uses the SparseArrays methods, whereas @mkls A * b uses the ones defined in this package. This way, toggling between the two would be straightforward.
I don't see how that would be straight forward if the A * b is e.g. in some other package.