28
$\begingroup$

How is + associated with Plus? Suppose I want to define a head FooBar and have it associated with a unicode character of my choice, ideally used as an infix form, i.e.

FooBar[x, y]

is equivalent

x ↗ y

as seen by the kernel. How this kind of thing can be done?

$\endgroup$
4
  • $\begingroup$ THe question is how is that achieved. Not that they are different. $\endgroup$
    – MathCraft
    Commented Aug 29, 2013 at 23:54
  • $\begingroup$ This has absolutely nothing to do with FE. In pure kernel session you observe the same behaviour. $\endgroup$
    – MathCraft
    Commented Aug 29, 2013 at 23:57
  • 3
    $\begingroup$ This interpretation of + is built into the parser. When the parser sees 1+2, it converts that to a representation equivalent to Plus[1,2]. You can't modify the parser. There are a number of operators which the parser already knows but don't have any built-in meaning (see halirutan's comment on UpperRightArrow) This is one of your options. If you go with the Notations package, you gain some flexibilty, but you are going to rely on the front end. This package relies on box representations. $\endgroup$
    – Szabolcs
    Commented Sep 3, 2013 at 15:59
  • $\begingroup$ Notations defined with that package are not usable in command line mode. $\endgroup$
    – Szabolcs
    Commented Sep 3, 2013 at 15:59

3 Answers 3

20
$\begingroup$

I can't answer how the association is made for the built-in operators, but I can show how to add your own. If your symbol is already an operator you can do this simply as halirutan showed.

This question may be a duplicate of How can one define an infix operator with an arbitrary unicode character? but since it admits a simpler interpretation I shall not close it as such. Drawing from both Jens' and my own answer we can do the following. It requires editing a low level system file, so make careful back-ups. The format is described in the linked Q&A.

Here I will define an entirely new operator I shall call PennyOp, with a Unicode character mapping and an input alias.

Find your UnicodeCharacters.tr file in SystemFiles\FrontEnd\TextResources\ or using the path given by:

System`Dump`unicodeCharactersTR

(at least in version 10.1 one can also copy this file to the matching path in $UserBaseDirectory)

and add this line:

0x20B0      \[PennyOp]      ($penny$)    Infix       155     None        5       5

You can then use EscpennyEsc to enter the operator, which is recognized as such:

Mathematica graphics

Adding Jens' MakeExpression definition:

MakeExpression[RowBox[{x_, "\[PennyOp]", y_}], StandardForm] :=
  MakeExpression[RowBox[{"PennyOp", "[", x, ",", y, "]"}], StandardForm]

Now:

enter image description here

You can define PennyOp as you would any other Symbol:

PennyOp[n_Integer, s_String] := "" <> Riffle[Table[s, {n}], " "]

5 \[PennyOp] "word"

"word word word word word"

Presto, custom Unicode-character operator with custom precedence and binding. It will only work in the Front End however.

$\endgroup$
3
  • $\begingroup$ It seems for me that it might be better set aliases $GAPackageInputAliases=Join[{},{"ip" ->RowBox[{" ","∙"," ","[SelectionPlaceholder]"}]; SetOptions[System$FrontEndSession,InputAliases -> Join[CurrentValue[System$FrontEndSession,InputAliases], $GAPackageInputAliases]]; and not to modify UnicodeCharacters.tr. At least I came to this conlusion after multiple attempts to introduce a number of infix operators with different precedences. $\endgroup$
    – Acus
    Commented Aug 2, 2015 at 12:43
  • $\begingroup$ @user18792 Editing UnicodeCharacters.tr is the only way I know to achieve this effect. Are you saying you ran into problems with this? What were they? If instead you are saying that it is better not modify system files and instead to use input aliases I cannot really disagree with that; this is undocumented behavior that could change or be removed at any time leaving one with a broken codebase. $\endgroup$
    – Mr.Wizard
    Commented Aug 2, 2015 at 16:52
  • $\begingroup$ I was unable to properly construct group of infix operations with strictly ordered preferences using this way. In order to understand my problem I formulated separate question "How to define a number of infix operators with predefined relative precedences". $\endgroup$
    – Acus
    Commented Aug 2, 2015 at 18:50
29
$\begingroup$

Maybe I miss the point here, but

FullForm[x ↗ y]

gives UpperRightArrow[x,y]. This is described in the documentation to UpperRightArrow and since this symbol is not protected and has not built-in meaning, you can just define it the way you like:

UpperRightArrow[x_, y_] := FooBar[x, y]

and this instantly gives you

Mathematica graphics

Update: As answer to Jacobs comment I want to point out, that I defined the FooBar definition so verbosely to show, that it works like a normal function definition. Of course, the most easy method is just to say

UpperRightArrow = FooBar

About your first question, I can only make an educated guess, because I don't know the implementation. The association of the infix + and the Plus happens during parsing, because what you see when you use something like FullForm[Expand[(a + b)^3]] is the parse tree after the expression was evaluated.

In the official docs, I found only in the tutorial Operators without Built-in Meanings a hint to your question:

When you enter a piece of input such as 2+2, Mathematica first recognizes the + as an operator and constructs the expression Plus[2, 2], then uses the built-in rules for Plus to evaluate the expression and get the result .

$\endgroup$
3
  • 1
    $\begingroup$ Darn, I forgot to even check if that was an operator first. +1 $\endgroup$
    – Mr.Wizard
    Commented Aug 30, 2013 at 1:05
  • $\begingroup$ I think the solution by Stephen gives you FooBar[x,y] even more instantly :P $\endgroup$ Commented Aug 31, 2013 at 12:52
  • $\begingroup$ @JacobAkkerboom But this has nothing to do with the Notation` package. You can do it exactly this way with normal symbols too. $\endgroup$
    – halirutan
    Commented Sep 3, 2013 at 23:39
15
$\begingroup$

The Notation package is the most convenient way to define new notation(s).

<<Notation`

Define an infix notation. You can use the palette that the 'Notation` package pops up to do this.

InfixNotation[ParsedBoxWrapper["\[UpperRightArrow]"], FooBar]

Check that the infix notation maps to the correct FullForm expression.

x \[UpperRightArrow] y // FullForm
$\endgroup$
2
  • $\begingroup$ Especially HoldComplete[a \[UpperRightArrow] b] // FullForm is impressive IMO. Does this require dynamic updating (whatever that is?). It did not work for me the first time, when I had turned that off. $\endgroup$ Commented Aug 31, 2013 at 12:50
  • 1
    $\begingroup$ @Jacob No, I don't believe it should require dynamic updating. This creates a MakeBoxes rule and matching MakeExpression rule. Because of this it will only work in the Front End, so it's usually better to just make an assignment to UpperRightArrow as halirutan did when the character is already an operator. $\endgroup$
    – Mr.Wizard
    Commented Sep 1, 2013 at 22:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.