7
$\begingroup$

Suppose I have a simple function that I assign to an operator

f[a_, b_] := a + b
CirclePlus = f

Then I want to write

1 (+) 2 (+) 3

But it doesn't work, because it's trying to evaluate f[1,2,3].

So how does one instruct Mathematica that it should instead evaluate f[f[1,2],3], or alternatively how does one work with infix operators? I'd be okay if I had to write my as f[a_List] instead, and then took care of things myself ...

-- Edit:

As the answer was deleted, note that making the function Flat is not the answer, here, as far as I can see.

-- Edit:

Here is an exact copy of the MMA file to reproduce this problem

In[13]:= f[a_,b_]:=a+b;
f[a_,b_,c_]:=f[f[a,b],c]
CirclePlus=f;
1\[CirclePlus]2\[CirclePlus]5\[CirclePlus]6
Out[16]= f[1,2,5,6]
$\endgroup$
10
$\begingroup$

You can tell it by making a definition what it should do if you have more then 2 arguments:

ClearAll[f];
f[a_, b_, c__] := f[f[a, b], c];
CirclePlus = f

Then you get

Mathematica graphics

And of course you have to add the definition of f when it is called as binary function. So for instance, and only for the purpose of showing what happens:

f[a_, b_] := Row[{"(", a, "\[CirclePlus]", b, ")"}]

Mathematica graphics

Here is how it looks when you use more than 3 terms. Note that the pattern is recursively applied until there are only 2 arguments in each call:

Mathematica graphics

$\endgroup$
  • $\begingroup$ This only works if I have only three terms; it doesn't make it generally associative (i.e. it doesn't work if there are 4 terms.) $\endgroup$ – Noon Silk Mar 22 '15 at 9:24
  • 3
    $\begingroup$ @NoonSilk And you say this because you have tried it? $\endgroup$ – halirutan Mar 22 '15 at 9:43
  • $\begingroup$ Yes, I did try it. Did you? $\endgroup$ – Noon Silk Mar 22 '15 at 9:44
  • $\begingroup$ So you don't get the same result that I get for the 5 arguments in my last example? $\endgroup$ – halirutan Mar 22 '15 at 9:47
  • $\begingroup$ No. This is what I have: In[13]:= f[a_,b_]:=a+b; f[a_,b_,c_]:=f[f[a,b],c] CirclePlus=f; 1[CirclePlus]2[CirclePlus]5[CirclePlus]6 Out[16]= f[1,2,5,6] $\endgroup$ – Noon Silk Mar 22 '15 at 9:49
5
$\begingroup$

halirutan demonstrated how to adapt your function f to handle multiple arguments but that changes the game: f is no longer a binary function.

The other aspect of this problem is that the CirclePlus operator itself is not binary; rather it accepts a series of arguments as illustrated in the question. CircleMinus is a binary operator, and with it your code works as written:

f[a_, b_] := a + b
CircleMinus = f;

q ⊖ r ⊖ s ⊖ t
q + r + s + t

This of course would be a confusing choice of operator for this function but it serves as illustration. An additional property that must be considered is left versus right association. CircleMinus is left-associative:

CircleMinus = foo;

q ⊖ r ⊖ s ⊖ t
foo[foo[foo[q, r], s], t]

Therefore is right-associative:

Therefore = foo;

q ∴ r ∴ s ∴ t
foo[q, foo[r, foo[s, t]]]

Care should be exercised when choosing an operator for your function!

$\endgroup$
  • $\begingroup$ Well, in my case I'm actually performing a matrix direct sum, so I wanted the direct sum symbol. And that operation is associative. So how do I make CirclePlus be associative in the way I want? $\endgroup$ – Noon Silk Mar 22 '15 at 22:51
  • $\begingroup$ @NoonSilk Theoretically you could edit the entry for CirclePlus in UnicodeCharacters.tr following the format described here (6363) but I strongly recommend against it as your code will only work on a similarly modified system. I recommend that you choose a different existing operator, or possibly create a new one as also described in the post linked above. $\endgroup$ – Mr.Wizard Mar 23 '15 at 3:40
  • $\begingroup$ Yeah, I won't be editing that file. It seems crazy that I can't make this operator associative! $\endgroup$ – Noon Silk Mar 24 '15 at 21:46
  • $\begingroup$ @NoonSilk I believe it is a design choice, not necessarily one that I defend, but at least one I think I understand. The operator associativity is a low-level property that affects parsing itself. User definitions are applied after parsing. Therefore to affect this one must edit low-level properties, i.e. UnicodeCharacters.tr. Mathematica simply isn't designed to allow low-level modification of the syntax itself; even resource files such as UnicodeCharacters.tr are only limited exceptions to this. One would have to write his own parser to define a truly custom language syntax. $\endgroup$ – Mr.Wizard Mar 25 '15 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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