Shorthand for map at level 2

Corrected to use SubscriptBox as Rojo showed and Kvothe commented, fixing binding.

Rojo shows a way in Is it possible to define custom compound assignment operators like ⊕= similar to built-ins +=, *= etc?

MakeExpression[RowBox[{f_, SubscriptBox["/@", n_], expr_}], StandardForm] := 
  MakeExpression @ RowBox[{"Map", "[", f, ",", expr, ",", "{", n, "}", "]"}]

Now, entered using Ctrl+-:

enter image description here

I actually used this (or code very like it) for a while but I got tired of having to translate to the long form for posting here so I stopped.

You could use a variation of you want to allow for full levelspec rather map at (only) level n.


Performance

Syntactically I like Kuba's suggestion of Map[f] /@ expr but I have personally rejected this as a general replacement for Map[f, expr, {2}], and I would like to illustrate why.

An aside: the only reason I am offering this critique is because I find this form desirable; I had the same reaction as march, just longer ago: "That's the usefulness of operator forms that I've been waiting for." I still hope that at least the performance aspect will be improved in future versions.

Unfortunately in the current implementation (or at least 10.1.0, but I don't think this has changed in v11) Operator Forms cannot themselves be compiled, therefore Map[f] /@ expr forces unpacking of expr. To make a contrived example where the Operator Form is at a stark disadvantage I shall use an array of many rows and few columns.

big = RandomReal[1, {500000, 3}];

Map[Sin] /@ big     // RepeatedTiming // First

Map[Sin, big, {2}]  // RepeatedTiming // First
1.16

0.0482
On["Packing"];
Map[Sin] /@ big;

Unpacking array with dimensions {500000,3} to level 1. >>

Unpacking array with dimensions {3}. >>

Unpacking array with dimensions {3}. >>

Unpacking array with dimensions {3}. >>

Further output of Developer`FromPackedArray::punpack1 will be suppressed during this calculation. >>

As LLlAMnYP commented one can see that the Operator Form is the problem here by comparing:

On["Packing"]

Sin /@ # & /@ big; // RepeatedTiming // First
0.0765

Here Sin /@ # & compiles and the operation is fast and no unpacking takes place.

Evaluation

At risk of belaboring a point there is another limitation or at least difference regarding Map[f] /@ expr: evaluation.

Compare:

Map[f, Hold[{a}, b, c], {2}]

Map[f] /@ Hold[{a}, b, c]
Hold[{f[a]}, b, c]

Hold[Map[f][{a}], Map[f][b], Map[f][c]]

Clearly these operations are not equivalent.


I'm not aware of a simple one, but perhaps you could make your own? The following is not great because it requires you to enter CenterDot as Esc+.+Esc, and you can't control the precedence, but depending on your use-case, it might be useful. In addition, you can use whatever built-in symbol with no built-in meaning you want:

CenterDot[f_, a_] := Map[f, a, {2}]

Then:

enter image description here

The CenterDot operator has no associativity which means that a string of input like a·b·c·d will be translated as CenterDot[a, b, c, d] which has no rule:

a·b·c·d // FullForm
CenterDot[a, b, c, d]

For this reason it is desirable to manually establish associativity:

CenterDot[a__, b_, c_] := a·(b·c)

Now:

a·Row[{b}]·Row[{c}]·Row[{d}]
a[b[c[d]]]    (*  Row[{a[Row[{b}][Row[{c}][d]]]}]  *)