The @ operator in Mathematica is right-associative by default, i.e.
f@g@h
evaluates as
f@(g@h)
Is it possible to make the @ operator evaluate the involved functions in a left-associative order (f@g)@h
instead?
The problem is that the conversion happens at parsing stage, not evaluation. And after code has been parsed, the details of how function was invoked (prefix, normal way or postfix) are not stored any more, so by the time you evaluate the code, you have no way to tell whether you typed it as f@g@h
, f[g[h]]
, or h // g // f
.
In the FrontEnd, you can do something like this:
Clear[fn];
fn[RowBox[{f_, "@", rest_}]] := fn[f, rest];
fn[before_, RowBox[{f_, "@", rest_}]] :=
fn[RowBox[{"(", RowBox[{before, "@", f}], ")"}], rest];
fn[before_, last_] := RowBox[{before, "@", last}];
fn[x_] := x;
followed by
$PreRead = fn;
Then,
f@g@h
(* f[g][h] *)
Note that the above code may not be totally robust, since it is based on interpreting box expressions, and I may have missed some possibilities. It should be possible to make it reasonably robust though, by extending to more cases.
Since a single @
, as far as I know, does not have any other meaning in Mathematica (other than a prefix function call), another option you have is to write a string preprocessor which will be called to preprocess your code before it is parsed by Mathematica parser, inserting parentheses as necessary. This method can probably be made to work for packages as well.
A similar question has been addressed here:
How can one define an infix operator with an arbitrary unicode character?
I strongly encourage you to add an operator, if necessary, rather than changing the behavior of the built-in one.
Nevertheless, if you are undeterred might be able to make this change in a similar fashion but I expect it to break the system if you are successful.
UnicodeCharacters.tr
file as well.
$\endgroup$
Commented
Oct 11, 2012 at 16:55
@
to behave differently shouldn't be sharing code anyway! :-@
$\endgroup$
Commented
Oct 11, 2012 at 16:58
obj@method1[args]@method2[args2]
and it will evaluate correctly from left to right. I want to mimic that method invocation syntax. $\endgroup$//
? $\endgroup$method1[obj, args]
). And if they wanted to have objects to the left, provide a general syntax (e.g. an extended infix syntax, transforminga~b~[...]
intob[a,...]
, so you could writeobj~method~[args]
, but also e.g.5~IntegerDigits~[2,3]
). $\endgroup$~infix~
has been a hard sell. :^) $\endgroup$