Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to do something like this:

In[1]:= ToExpression["\"\\[CirclePlus]\""]
Out[1]= ⊕

In[2]:= list_ ⊕ element_ := Append[list, element];

In[3]:= a = {1, 2};

In[4]:= {a = a ⊕ 3, a}
Out[4]= {{1, 2, 3}, {1, 2, 3}}   

In[5]:= {a ⊕= 4, a}

(* Desired result: Out[5]= {{1, 2, 3, 4}, {1, 2, 3, 4}} *)
(* Actual result: syntax error *)

Syntax::sntxf: "a⊕" cannot be followed by "=4".

Is it possible to workaround this error and make the compound assignment operator ⊕= work?

share|improve this question
    
Infact CirclePlus[x_List, y_] := Append[x, y] works. Then you can try things like "{1,2,3} \ [CirclePlus] 4". –  Ali Jun 16 '13 at 5:13
    
I tried something along these lines: reference.wolfram.com/mathematica/tutorial/…, but failed. –  Vladimir Reshetnikov Jun 16 '13 at 5:51
3  
Unfortunately, you cannot define new operators like this. You can have the operator itself, but not the sigil to represent it, as it seems that the parser is not user-programmable. If it were, the Notation` package wouldn't be needed. –  Oleksandr R. Jun 16 '13 at 6:16
2  
You can have it if you can live with using an input alias (esc + sth + esc) to input it. If you build your operator from other operators with sub-super-under-etcscripts, then it is more straighforward. Are you interested in any of these solutions? –  Rojo Jun 16 '13 at 18:46
2  
I would add one caution: \[CirclePlus], etc. are System` symbols, and while they do not have any defined behavior (which makes them nice to overload), adding a definition will seemingly "break" the encapsulation of unique notebook or cell group contexts. The key is they're essentially global, so if you define them in one place, the definition is accessible without any qualifications. Yes, I've done this to myself. –  rcollyer Jun 18 '13 at 15:49

3 Answers 3

This is my little test, and I encountered with some problems.

 (*Input 1 ==< *)
 (list_) \[CirclePlus] (element_) := Append[list, element]; 

 (*Input 2 ==< *)
 (x_List) \[CirclePlus] (y_) := Append[x, y]

Failed try.

 (*Input 3 ==< *)
 CircleAddTo[x_List, y_] := AppendTo[x, y]

 (*Input 4 ==< *)
 CircleAddTo[{1, 2, 3}, 6]
(*
 Output==>
 AppendTo[{1,2,3},6]
*)
 (*Input 5 ==< *)
 a = {1, 2, 3, 4}; 

Use one new variable name z

 (*Input 6 ==< *)
 Clear[CircleAddTo]

 (*Input 7 ==< *)
 CircleAddTo[x_List, y_] := (Clear[z]; z = Append[x, y])

 (*Input 8 ==< *)
 {CircleAddTo[a, 10], a}
(*
 Output==>
 {{1,2,3,4,10},{1,2,3,4}}
*)
 (*Input 9 ==< *)
 {CircleAddTo[a, 10], z}
(*
 Output==>
 {{1,2,3,4,10},{1,2,3,4,10}}
*)

one method use string symbol

Convert CircleAddTo to string symbol $\text{$\oplus $=}$

 (*Input 10 ==< *)
 Interpretation["\[CirclePlus]=", CircleAddTo]; 

 (*Input 11 ==< *)
 {a~"\[CirclePlus]="~7,z,a}
(*
 Output==>
 {{1,2,3,4,7},{1,2,3,4,7},{1,2,3,4}}
*)

Of couse,we could use one New Sybmol to replace the compound symbol $\oplus =$

 (*Input 12 ==< *)
 (a_) \[CircleTimes] (b_) := CircleAddTo[a, b]

 (*Input 13 ==< *)
 a \[CircleTimes] 9
(*
 Output==>
 {1,2,3,4,9}
*)
 (*Input 14 ==< *)
 {z, a}
(*
 Output==>
 {{1,2,3,4,9},{1,2,3,4}}
*)

or

 (*Input 15 ==< *)
 p = CircleAddTo; 

 (*Input 16 ==< *)
 {a~p~7, z, a}
(*
 Output==>
 {{1,2,3,4,7},{1,2,3,4,7},{1,2,3,4}}
*)

NotationPackage


Notation/tutorial/NotationSymbolizeAndInfixNotation

 (*Input 17 ==< *)
 << "Notation`"

 (*Input 18 ==< *)
 Cell[BoxData[RowBox[{"InfixNotation", "[", RowBox[{TemplateBox[{SubscriptBox["\[CirclePlus]", "="]},"NotationTemplateTag"], ",","CircleAddTo"}], "]"}]], "Input"]

enter image description here

 (*Input 19 ==< *)
 CircleAddTo[a, 6]
(*
 Output==>
 {1,2,3,4,6}
*)
share|improve this answer

Best option in my view is to use a compound operator based on an already defined operator, whose precedence is inherited, with the Notation package or by redefining MakeExpression.

MakeExpression[
  RowBox[{b___, x_, UnderscriptBox["=", "\[CirclePlus]"], y_, a___}], 
  StandardForm] := 
 MakeExpression[
  RowBox[{b, RowBox[{"gplus", "[", RowBox[{x, ",", y}], "]"}], a}], 
  StandardForm]

This underscript is probably quite weird but you can do as you wish (probably an overscript made more sense). As it is, your operator is an equal sign with an underscripted circle plus. However, some boxes are transparent for parsing, so you could define the following input alias for a different layout of the operator

PrependTo[CurrentValue[InputNotebook[], InputAliases], 
 "c+=" -> FrameBox[UnderscriptBox["=", 
       AdjustmentBox["\[CirclePlus]",
         BoxBaselineShift -> -2.5,
         BoxMargins -> {{-0.7638888888888887, 
        0.7638888888888887}, {2.5, -2.5}}]],
   BoxFrame -> False, FrameMargins -> {{5, 0}, {0, 0}}]]

There's also the option to redefine MakeExpression directly on a TagBox of a RowBox, or to use some box in which the lhs and the rhs of the operation are parts of it (this is probably the simplest way), but I'd stay with the first option.

share|improve this answer

According to Michael Pilat this is not possible, at least generally.

I major issue with any attempted hack is getting precedence correct. Perhaps the simplest would be a replacement with an already defined or new single-character operator with an established precedence. This is easier said than done however as replacement done at the string level requires a custom input cell type and complicates entry of advanced forms.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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