2

Why does this only work after running the evaluation 2 times?

diff[var1_, y0_, funk_, {var2_, a_, b_}, N_] := ( 

 Module[{h},

  var1 := #1;
  var2 := #2;
  h = (b - a)/N;

  FoldList[var1 + h*funk &, y0, Range[a, b - h, h]] ])

Evaluation the first time

diff[y, 2, -t y^2, {t, 0., 2}, 20]
{2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 0.1 #1^2 #2, #1 - 
0.1 #1^2 #2, #1 - 0.1 #1^2 #2}  

Evaluation the second time

diff[y, 2, -t y^2, {t, 0., 2}, 20]
{2, 2., 1.96, 1.88317, 1.77678, 1.6505, 1.51429, 1.37671, 1.24404, 1.12023,
    1.00728, 0.905822, 0.815565, 0.735748, 0.665376, 0.603394, 0.548781, 0.500596, 
    0.457994, 0.420238, 0.386684}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Punchline
  • 97
  • 4

1 Answers1

5

This is malformed code with some strange effects. In the first evaluation y is substituted for var1 in var1 := #1 therefore after the first evaluation the global Symbol y has the assigned value #1 (Slot[1]). When the expression is evaluated a second time this value is substituted into the inner function var1 + h*funk & by the main definition for diff making it #1 + h*funk & and it then operates.

What were you attempting to do with this code?


I believe your desired functionality may be had by using named parameters in Function rather than Slot parameters. Consider:

diff[var1_, y0_, funk_, {var2_, a_, b_}, N_] :=
  Module[{h},
   h = (b - a)/N;
   FoldList[Function[{var1, var2}, var1 + h*funk], y0, Range[a, b - h, h]]
  ]

diff[y, 2, -t y^2, {t, 0., 2}, 20] (* first evaluation *)
{2, 2., 1.96, 1.88317, 1.77678, 1.6505, <<>> 0.386684}

You can ignore the red syntax highlighting which is warning of possible name collision because that happens to be what you want. Note that automatic renaming does take place here, but since the renaming is uniform in both the named Function parameters and the body that you inject (funk_) I do not believe this is a problem. Here is a look at the Function produced that is used by FoldList:

diffX[var1_, y0_, funk_, {var2_, a_, b_}, N_] :=
 Module[{h},
  h = (b - a)/N;
  Function[{var1, var2}, var1 + h*funk]
 ]

diffX[y, 2, -t y^2, {t, 0., 2}, 20]
Function[{y$, t$}, y$ + h$579 (-t$ y$^2)]

Observe that t has been renamed to t$ in all appearances.

You may wish to add the HoldAll attribute to diff, as without it a global assignment to y or t will cause failure.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371