Defining indefinitely many functions

Is it possible to define a class of indefinitely many functions f1, f2, f3, ... such that f1[x] becomes x + 1, f2[x] becomes x + 2, f3[x] becomes x + 3 and so on.

I want f25[100] to produce 125, and f255555555[333] to produce 255555888.

I am aware of the following: If I define

f[n_][x_] := n + x


then f[1][x] becomes x + 1, f[2][x] becomes x + 2 and so on. But, f[1] is longer and looks messier than f1.

I want my functions names to be f1, f2, f3, ... not f[1], f[2], f[3] ....

• "But, f[1] is longer and looks messier than f1." — This is absolutely a terrible justification for doing this and I really hope beginners reading this don't get into such a habit. Not worth wasting time to save 2 characters, IMO.
– rm -rf
Oct 2 '15 at 4:28
• Are you interested only in integers or also in Rationals, Reals and Complexes?. A symbolic extension would be also a nice touch. Something like fail[x] becoming x + ail Oct 2 '15 at 4:30
• You have demonstrated that you know the correct method for doing what you are interested in doing. Leave it at that and move on. Oct 2 '15 at 4:44
• Use Format[f[n_][x_]] := Subscript[f, n][x]; to "prettify" the display. Oct 2 '15 at 5:52
• @TheToad I agree, it's bad for most intents and purposes, but personally I'd also sometimes like to do something similar. The problem with f[1] over f1 is that f1 is a symbol, while f[1] is a DownValue of the symbol f. One can do f1[[3]]=c but not f[1][[3]]=c. +1 to the Q, I've learned about $NewSymbol today thanks to it. Oct 2 '15 at 6:31 5 Answers Agree with other answers, this is a bad idea (why, precisely do you want to do this?), but in the spirit of encouraging unmaintainable write-once read-never code, here's my entry into the freak show: $NewSymbol = If[StringMatchQ[#, "f" ~~ NumberString],
ToExpression[# <> "[x_]=x+" <> StringDrop[#, 1]]] &;

Remove["f*"];

f123[10] + f15[2]

(* 150 *)


All sorts of agathokakological connotations and incantations within.

In the words of the G-Man, "Prepare for unforeseen consequences" with any of the answers....

• +1 for showing us $NewSymbol Oct 2 '15 at 6:31 • +1 for showing us "agathokakological" :^) Jul 20 '16 at 22:00 Just to be clear, I think this is a terrible idea but nevertheless, a question has been posed for which there is a simple answer: ClearAll@fn SetAttributes[fn, HoldAll] fn[h_[x_]] /; StringMatchQ[SymbolName@h, "f" ~~ DigitCharacter ..] := First@StringCases[SymbolName@h, "f" ~~ d : DigitCharacter .. :> x + ToExpression@d] fn[x___] := x$Pre = fn


Now f1234[5678] will behave as you wanted.

Extending this to handle cases when f1234 already has an existing definition or replacing f1234[x] anywhere within an expression is left as an exercise.

In the interest of illustrating why what you've requested might be a bad idea, here's the simplest way I can think of to achieve your goal (there may be a better way):

Do[(ToExpression["f" <> ToString[#]][x_] := x + #) &@ic, {ic, 1, 5}]
?f1
?f5


It's much messier than the two characters you'd like to save and harder to index programatically, so I'd stick to f[n][x].

You can get the desired look using the Notation Package.

<< Notation

Notation[ParsedBoxWrapper[RowBox[{"f", " ", RowBox[{"n_", "[", "x_", "]"}]}]]
\[DoubleLongRightArrow]
ParsedBoxWrapper[RowBox[{RowBox[{"f", "[", "n_", "]"}], "[", "x_", "]"}]]]


which is displayed as

when the Notation Palette is used to create the second part of the above code and \[InvisibleSpace] (or EscisEsc) is used between f and n_.

With

f[n_][x_] := x + n


now

f 25[100]


or

f\[InvisibleSpace]25[100]


will both result in
125
while the last input is displayed as

As others have said, this is a bad idea. However, if you only care about the appearance of f, then you could so something like this:

f // ClearAll;

intF = RowBox[ { RowBox[ { "f", "[", #1, "]" } ], "[", #2, "]" } ] &;
dspF = RowBox[ { "f", #1, "[", #2, "]" } ] &;

f /: MakeBoxes[ f[ n_ ][ x_ ], form_ ] :=
With[ { ns = ToString @ n, xs = ToString @ x, if = intF, df = dspF },
TemplateBox[ { ns, xs }, "f",
InterpretationFunction :> if,
DisplayFunction :> df
]
];


All this really does is change the appearance of f[n][x]. So now you get results that look like this:

However, it could get tedious to copy and paste the boxed version whenever you want your input to be displayed this way. As an alternative (which I think looks nicer too), you can use SubscriptBox instead:

f // ClearAll;

intF = RowBox[ { "f", "[", #1, "]" } ] &;
dspF = SubscriptBox[ "f", #1 ] &;

f /: Subscript[ f, n_ ] := f @ n;

f /: MakeBoxes[ f[ n_ ], form_ ] :=
With[ { ns = ToString @ n, if = intF, df = dspF },
TemplateBox[ { ns }, "f",
InterpretationFunction :> if,
DisplayFunction :> df
]
];
`