On 10/11/10 at 5:15 AM, sschmitt at physi.uni-heidelberg.de (Sebastian
Schmitt) wrote:
>I'm new to Mathematica with a background mostly in C++. Many times I
>have the impression that my style is not natural-Mathematica
>(Mathematicaesque so to say).
>If I have a For loop in a function like this:
>In[39]:= f[x_] := Module[{},
>For[i = 0, i != x, i++,
>Print[i]
>]
>]
>In[41]:= f[2]
>During evaluation of In[41]:= 0
>During evaluation of In[41]:= 1
>In[42]:= i
>Out[42]= 2
>I was surprised to find "i" being not local to the For loop. Do I
>have to keep track of all my throw-away-variables and put them in
>the list of local variables of the Module?
Yes, if you are going to use For. No, if you simply don't use
For. While For exists in Mathematica there is very little need
to use For if any at all. I would have written the function
above as:
f[x_]:=Table[Print[k-1],{k,x}]
The variable k is localized as can be verified by:
In[1]:= f[x_] := Table[Print[k - 1], {k, x}]
In[2]:= f[2];
During evaluation of In[2]:= 0
During evaluation of In[2]:= 1
In[3]:= k
Out[3]= k
Notice also, the syntax coloring. That is before executing
For[k = 0, k!=x, k++, Print[k]]
You will see the color of the variable k is the same as the
color for any symbol that does not have an assigned value. But,
the color of k in
Table[Print[k-1],{k,x]
is not the same as the color of a variable with no assignment.
And the color doesn't change after this is executed as it does
in the case of For.
Note, in the above example I used a semicolon after f[2]. Table
is intended to generate a List. Since Print has no output, the
list generated is simply a list of Nulls. Normally, you would be
doing something in the body of Table that would output something
other than Null. But if you do intend not to generate usable
output, it would be better to define this function with
something that doesn't generated a list, e.g. Scan. Using Scan,
this function would be written as:
f[x_]:=Scan[Print[#-1]&, Range[x]]
And since there is no explicit iterator, this function
definition should be a bit more efficient than the one using Table
And if you need more convincing as to why not to use For
consider the following:
In[1]:= n = 10^6;
In[2]:= Timing[sum = 0; For[k = 0, k <= n, k++, sum += k]; sum]
Out[2]= {2.61311,500000500000}
In[3]:= Timing[Plus @@ Range[n]]
Out[3]= {0.371559,500000500000}
In[4]:= Timing[Total[Range[n]]]
Out[4]= {0.34012,500000500000}
In[5]:= Timing[Sum[k, {k, n}]]
Out[5]= {0.393106,500000500000}
In[6]:= Timing[Sum[k, {k, m}] /. m -> n]
Out[6]= {0.08371,500000500000}
Each code snippet does exactly the same thing and produces
exactly the same sum. But as you can see, using For is the
slowest method.