The default behavior of the character .
between two non-numeric characters is to be interpreted as the infix of the Mathematica function Dot
.
Is there a command that can be placed in a package to get the front-end to parse .
as an infix for another function -- say user-defined one, myDot[]
?
That is,
a.b
should be interpreted asmyDot[a, b]
myDot[a.b]
should map toa.b
Dot[a,b]
should not get mapped toa.b
, but the functionality of the built-in functionDot
should not be lost.3.14
should remain a single number, where here the dot indicates a decimal separator.
Answer
Updated
First, let's stop Dot
from creating these box structures.
MakeBoxes[Dot[x__], form_] :=
RowBox[{"Dot", "[", RowBox@Riffle[MakeBoxes /@ {x}, ","], "]"}]
Next, let's specify that these structures should instead be interpreted as myDot
:
MakeExpression[RowBox@(row : {PatternSequence[_, "."] .., _}), form_] :=
MakeExpression[
RowBox@{"myDot", "[", RowBox@Riffle[row[[1 ;; -1 ;; 2]], ","], "]"}, form]
The slicing and riffling is ugly... there is probably a cleaner way to do it. ReplacePart
seemed to be doing weird things when I tried it but I didn't spend any time on it.
The last step is to specify that myDot
should also be rendered into the same structure:
MakeBoxes[myDot[x__], form_] := RowBox@Riffle[MakeBoxes /@ {x}, "."]
Now,
Dot[a, b, c]
Dot[a, b, c]
Dot[{a, b, c}, {x, y, z}]
a x + b y + c z
a.b.c
a.b.c
a.b.c // FullForm
myDot[a, b, c]
{a, b, c}.{x, y, z} // InputForm
myDot[{a, b, c}, {x, y, z}]
a.(b^2).c
a.b2.c
% // InputForm
myDot[a, b^2, c]
In all cases you will have to use MakeExpression
to override the interpretation of user input, but you may also find TagBox
and InterpretationBox
interesting alternatives to the MakeBoxes
implementations above.
Comments
Post a Comment