Here's a spiel I wrote about the subject and haven't yet integrated into other text on it.
Other bilinear operators can be expressed in terms of the tensor product by use of tracing operators or `contraction': these act on a given linear space in terms of a natural representation of it as U&tensor;T&tensor;V&tensor;G&tensor;W for some linear spaces U, V, W (each merely a passive passenger in proceedings and potentially just {scalars}) and a dual pair of linear spaces, T and G. A member of this tensor product space is expressible as a finite sum in which each term has the form u×t×v×g×w and the trace operation maps each such term to u×v×w.g(t) in which g(t) is a scalar, so this is equivalently u×g(t).v×w and etc. The result of summing trace's action on such terms emerges as a linear function on the entire span, yielding answers in U&tensor;V&tensor;W.
We can also combine trace and permutation to define a family of operators which, as it turns out, all differential operators will recognise as constant: all bilinear operators can be expressed using such. These I'll denote using τ(template, factorisation), in which the template and factorisation will be lists and will be of equal length, call it N. The factorisation will be a list of linear spaces: the tensor product of that list (eg the product of [U,V,W] will be U&tensor;V&tensor;W) tells us the linear space on which the operator acts, including that we are to read it in terms of this factorisation. Thus the operator will be specified in terms of its action on a single `typical' element of the linear space, expressed as a list of `vectors', each of which is a member of the linear space in the factorisation at the corresponding position in its list. Its action on the rest of the space is inferred by linear extension, exploiting the linearity of its action on typical elements.
Just as each vector is in the space at the corresponding position in the factorisation, so the corresponding position in the template tells us what to do with that vector in building the operator's result when given a typical element. Each entry in the template will either appear twice or be a natural number, indicating a position in a list numbered [..., 1, 0] that we'll be building. If an entry in the template is a natural number and only appears once, we put its associated vector in the position, in this new list, numbered by the given natural. If an entry in the template isn't a natural I'll call it a symbol: it appears in two places; and the two spaces, in the factorisation list at corresponding positions, must be dual to one another. We can thus combine the two vectors at corresponding positions to get a scalar, using the dual action. We multiply together all scalars obtained by such contractions and use the result to scale our final answer. The remaining case of a repeated natural is handled analogously: there must be a natural linear contraction defined between the spaces at the two corresponding positions in the factorisation; which enables us to combine the two elements from our list of vectors to form a vector quantity, of some kind, which we put into our new list at the position given by the natural number that was repeated. A valid template will always, by now, have produced a list with no gaps in it: subject to scaling obtained from any contractions, the tensor product of the entries in this list is our answer for the typical element we were given.
Note that, where a space appears several times in a factorisation list, templates which simply permute the order of those entries in the list, leaving the rest of the factorisation unmoved, produce answers in the same space as their input: so we can ask for the difference between input and output; they may even be equal, but needn't be.
Written by Eddy.