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.bshould be interpreted asmyDot[a, b]myDot[a.b]should map toa.bDot[a,b]should not get mapped toa.b, but the functionality of the built-in functionDotshould not be lost.3.14should 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