Skip to main content

custom notation - How to re-parse (or re-map) character '.' to user-defined function


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,




  1. a.b should be interpreted as myDot[a, b]





  2. myDot[a.b] should map to a.b




  3. Dot[a,b] should not get mapped to a.b, but the functionality of the built-in function Dot should not be lost.




  4. 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