TagSetDelayed¶
Defines a delayed upvalue assignment associated with a tag symbol. The
tag /: lhs := rhs shorthand is the usual way to write it.
Upvalues attached to Plus, Times and Power also apply to the arithmetic
shorthands that expand to those heads: a - b is Plus[a, Times[-1, b]],
a / b is Times[a, Power[b, -1]] and -a is Times[-1, a].
$ wo 'mytag /: mytag[a_] + mytag[b_] := mytag[a + b]; mytag /: i_Integer mytag[a_] := mytag[a i]; mytag[3] - mytag[3]'
mytag[0]
Together they implement modular arithmetic, where m[a, n] stands for
a modulo n:
$ wo 'm /: m[a_, n_] + m[b_, n_] := m[Mod[a + b, n], n]; m /: c_Integer m[a_, n_] := m[Mod[c a, n], n]; m[3, 7] - m[6, 7]'
m[4, 7]
The tag has to sit where the stored rule can be found again, but the wrappers that only name a pattern or restrict it are transparent — which is how an object system writes its formatting rule:
A tag buried deeper than that has nowhere to hang the rule, and nothing is defined:
$ wo 'obj /: fmt[wrap[obj[_]]] := 1; Length[UpValues[obj]]'
TagSetDelayed::tagpos: Tag obj in fmt[wrap[obj[_]]] is too deep for an assigned rule to be found.
0
An assignment also consults the upvalues of the symbols on its right, so a
symbol can give sym := f[…] a meaning of its own:
An upvalue on Set sees the right-hand side's value, which Set works out
once. Here the constructor runs once however many times the body names it: