Should I define a function or not?

I was trying to execute the following code:

form[n_, m_, r_] := (
{large, small} = Sort[{n, m}, Greater]; diff = Abs[large - small];
output =
Exp[-r^2/4]*Sqrt[Factorial[small]/Factorial[large]]*(r/Sqrt[2])^
diff*LaguerreL[small, diff, r^2/2];
Return[output];
);
num = 50;
fnm[r_] := Table[form[n, m, r], {n, 0, num}, {m, 0, num}];
list = Table[Random[Complex], {i, 0, num}, {j, 0, num}];
table1[r_] :=
Table[Conjugate[list[[n1, m1]]]*fnm[r][[n1, m1]]*
list[[n2, (n2 - n1) + m1]]*fnm[r][[n2, (n2 - n1) + m1]], {n1, 1,
num + 1}, {m1, 1, num + 1}, {n2, Max[n1 - m1 + 1, 1],
Min[num + 1, n1 - m1 + num + 1]}];
sum[r_] := Total[Flatten[table1[r]]];
result = NIntegrate[sum[r], {r, 0, ∞}];


This code is extremely slow in constructing table1[r], and it takes more than two seconds to construct each element in table1[r]. However, if I remove the function definition, and simply use

form[n_, m_, r_] := (
{large, small} = Sort[{n, m}, Greater]; diff = Abs[large - small];
output =
Exp[-r^2/4]*Sqrt[Factorial[small]/Factorial[large]]*(r/Sqrt[2])^
diff*LaguerreL[small, diff, r^2/2];
Return[output];
);
num = 50;
fnm = Table[form[n, m, r], {n, 0, num}, {m, 0, num}];
list = Table[Random[Complex], {i, 0, num}, {j, 0, num}];
table1 =
Table[Conjugate[list[[n1, m1]]]*fnm[[n1, m1]]*
list[[n2, (n2 - n1) + m1]]*fnm[[n2, (n2 - n1) + m1]], {n1, 1,
num + 1}, {m1, 1, num + 1}, {n2, Max[n1 - m1 + 1, 1],
Min[num + 1, n1 - m1 + num + 1]}];
sum = Total[Flatten[table1]];
result = NIntegrate[sum, {r, 0, ∞}];


the table1 variable is constructed almost instantly. So my question is:

1. Why is there such a big difference by removing the functional definition?
2. In general when should one use the functional definition, when should not?

By the way, I was trying to redefine fnm[r_] as fnm[r_?NumberQ], but in this case the table of fnm was not even generated, because of the NumberQ constraint. Did I use NumberQ incorrectly?

• Changing output = Exp[-r^2/4]* Sqrt[Factorial[small]/ Factorial[large]]* (r/Sqrt[2])^diff* LaguerreL[small, diff, r^2/2]; Return[output]; to just output = Exp[-r^2/4]* Sqrt[Factorial[small]/ Factorial[large]]* (r/Sqrt[2])^diff* LaguerreL[small, diff, r^2/2] without a trailing ; would probably be better. Return has a history of odd behavior and is often not needed. – Bill Jan 18 '16 at 6:48

(1) The time difference comes from the way fnm is evaluated differently. In the first code block, you evaluate fnm at every step in the Table in table1, and then you take parts of it, but you only need to evaluate it once as it does not depend on any of the iteration variables n1,m1,n2. This is what you do in the second code block: you calculate the fnm table once, and then you just access it in the table1 Table. A way to do this while keeping the := definitions is
fnm[r_] := Table[form[n, m, r], {n, 0, num}, {m, 0, num}];