Prefix operator with low precedence
As explained by Michael Pilat you cannot create your own compound operators* with custom precedence. (You could conceivably write your own parser as Leonid has worked on, or attempt to coerce the Box form with CellEvaluationFunction
.)
You can however use an existing operator with the desired precedence. Looking at the table Colon
appears to be a good choice. The operator is entered with Esc:
Esc. Example:
SetAttributes[Colon, HoldAll]
Colon[f__, x_] := Composition[f][Unevaluated@x]
ListPlot \[Colon] Flatten \[Colon] Log@N@Accumulate@# & /@ Partition[Range@300, 100]
Which appears as, and produces:
Since raw colon is already used for Pattern
this may be confusing. However, if you are willing to edit your UnicodeFontMapping.tr
file you can assign any symbol you like. Here I mapped \[Colon]
to Klingon A:
This was done by changing the line starting with 0x2236
in UnicodeFontMapping.tr
.
* Rojo demonstrated that one can create two-dimensional compound operators, meaning use of SubscriptBox
, SuperscriptBox
, OverscriptBox
, etc. See:
- Is it possible to define custom compound assignment operators like ⊕= similar to built-ins +=, *= etc?
This doesn't really answer your question, but perhaps the introduction of operator forms like Map[f]
in M10, as well as a new short form for Composition
will satisfy you. For example, in M10+ you can do:
ListPlot @* Flatten @* Log @* N @* Map[Accumulate] @ Partition[Range @ 300, 100]
Update
An even simpler alternative is to use a TemplateBox
so that an additional MakeExpression
rules is not needed (as in my original answer):
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "\\"}] = TemplateBox[
{},
"Prefix",
DisplayFunction -> ("\\\\"&),
InterpretationFunction -> ("@"&),
SyntaxForm -> "\[Colon]"
];
Simple example:
Hold[foo \\ x>2]
Hold[foo @ x>2]
Hold[foo[x > 2]]
Hold[foo[x] > 2]
Your more complicated example:
Hold[ListPlot \\ Flatten \\ Log@N@Accumulate@# & /@ Partition[Range@300,100]]
Hold[ListPlot[ Flatten[(Log[N[Accumulate[#1]]] &) /@ Partition[Range[300], 100]]]]
Original answer
It turns out that "\\" tokenizes, so it is possible to achieve your goals by using InputAutoReplacements
and MakeExpression
. First, use InputAutoReplacements
to lower the precedence of "\\":
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "\\"}] = TagBox[
"\\\\", Identity, SyntaxForm -> "\[Colon]"
];
Then, use MakeExpression
to parse such boxes correctly:
MakeExpression[RowBox[{a_, TagBox["\\\\", __], b__}], StandardForm] := MakeExpression[
RowBox[{a, "[", RowBox[{b}], "]"}],
StandardForm
]
Your example:
Hold[ListPlot \\ Flatten \\ Log@N@Accumulate@# & /@ Partition[Range@300,100]]
Hold[ListPlot[ Flatten[(Log[N[Accumulate[#1]]] &) /@ Partition[Range[300], 100]]]]
Hold[ListPlot[Flatten[Log@N@Accumulate@# & /@ Partition[Range@300, 100]]]]
Hold[ListPlot[ Flatten[(Log[N[Accumulate[#1]]] &) /@ Partition[Range[300], 100]]]]