How do I display function application with square brackets in traditional form?

If I type

C[x, y] // TraditionalForm

I get something that looks like

C[x, y]

But if I type

f[x, y] // TraditionalForm

I get something that looks like

f(x, y)

What do I do to designate that a particular symbol, say, f, should have function application rendered in traditional form with square brackets rather than parentheses (i.e., ToString[f[x], TraditionalForm] should give "f[x]", not "f(x)")?

Update: Using kguler's answer, I managed the following:

Block[{f},
RowBox[{"f", "(", else___, ")"}] :> RowBox[{"f", "[", else, "]"}]]];

But this does not work in all cases, in particular, when wrapped in a Defer block:

{g[g[h[x]]], g[f[h[x]]]} // TraditionalForm
{g[g[x] | y],  f[g[x] | y]} // TraditionalForm
{g[x, y | z, y], f[x, y | z, y]} // TraditionalForm
{Defer[g[D[k, x]]], Defer[f[D[k, x]]]} // TraditionalForm
{g[Defer[D[k, x]]], f[Defer[D[k, x]]]} // TraditionalForm

gives

$\{g (g (h(x))),g(f[h(x)])\}$

$\{g (g(x)\,|\,y),f[g(x)\,|\,y]\}$

$\{g(x,y\,|\,z,y),f[x,y\,|\,z,y]\}$

$\left\{g\left(\frac{\partial k}{\partial x}\right),f\right\}$

$\left\{g\left(\frac{\partial k}{\partial x}\right),f\left[\frac{\partial k}{\partial x}\right]\right\}$

The second-to-last line is wrong.

You can write a function that processes the boxforms produced by TraditionalForm to replace the parentheses by square brackets:

TraditionalForm/@{C[x,y], Sin[x], f[x,y], H[x], h[x,y,z], H[x,y], h[{x,y}]}
(* {C[x,y], sin(x), f(x,y), H(x), h(x,y,z), H(x,y), h({x,y})} *)

tF/@{C[x,y], Sin[x], f[x,y], H[x], h[x,y,z], H[x,y], h[{x,y}]}
(* {C[x,y], sin[x], f[x,y], H[x], h[x,y,z], H[x,y], h[{x,y}]} *)

Update:

ClearAll[tF2]
tF2 = Module[{f = ToString@#2}, RawBoxes[MakeBoxes[TraditionalForm[#]] //.
RowBox[{f, "(", else___, ")"}] :> RowBox[{"f", "[", else, "]"}]]] &;

tF2[#, f] & /@ {h[f[g[x]]], h[f[g[x, f[z, w]]]]}
{h (f[g (x)]), h (f[g (x, f[z, w])])}

Update 2: You can also define the traditional form formatting of f using TagSetDelayed:

ClearAll[makeBracketsF, f]
makeBracketsF[ f_] := (f /: MakeBoxes[f[a___], TraditionalForm] :=
RowBox[{ToString@f, "[", MakeBoxes[Row[{a}, ","], TraditionalForm], "]"}])

makeBracketsF[f]

{g[x, y | z, y], f[x, y | z, y]} // TraditionalForm
{Defer[g[D[k, x]]], Defer[g@f[D[k, x], u, f[r, s], t]]} // TraditionalForm • I want to tag a particular function symbol to give me square brackets in TraditionalForm, not to have all functions give me square brackets in TraditionalForm. i.e., if I run MakeBrackets[f] and then h[f[g[x]]]//TraditionalForm, I want to see h(f[g(x)]). – Jason Gross Mar 21 '15 at 0:44
• @JasonGross, please see the update. – kglr Mar 21 '15 at 1:04
• That is much better. I tried using Format[f[x__], TraditionalForm] := ... with that, but it does not work inside a Defer block. Can you make the examples I updated the question with work? – Jason Gross Mar 21 '15 at 1:23
• @JasonGross, try MakeBoxes in place of ToBoxes. MakeBoxes >> Properties and Relations: MakeBoxes[expr] does not evaluate expr, while ToBoxes[expr] does. – kglr Mar 21 '15 at 2:44

I would do this by defining a MakeBoxes rule for f as kglr does in his answer, but I would use the following version instead:

MakeBoxes[f[x__], fmt:TraditionalForm] ^:= RowBox[{
"f", "[", RowBox[Riffle[BoxForm`ListMakeBoxes[{x}, fmt], ","]], "]"
}]

The difference between his MakeBoxes definition and the above is that the above version produces the correct output when copy/pasted. For example, when g uses his MakeBoxes rule, copying the output of g[x, y] produces:

g[Row[{x, y}, ","]]

g[x, y]

I believe it is because some upper-case letters are interpreted as functions

(* $K[x,y]$ *)

Note that K is a system name

?? K

(* $K$ is a default generic name for a summation index in a symbolic sum. *)

However, letters that are not functions are not:

(* $B(x,y)$ *)

All lower-case functions are interpreted as arrays or matrics:

c[x, y] // TraditionalForm

(* $c(x,y)$ *)

If you want to keep the brackets:

c[x, y] // HoldForm

(* c[x,y] *)

• I want the arguments to the function, and the function symbol itself, redered in TraditionalForm; HoldForm does not do this. – Jason Gross Mar 21 '15 at 0:46