Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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}
share|improve this question
add comment

1 Answer

up vote 5 down vote accepted

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.

share|improve this answer
1  
The list from the second evaluation is what i need to proceed. (The list is correct). What i tried to do is assaign the varibles (y and t) to #1 and #2, so it was possible to use with any "funk" input. (fx -t y^2) –  Punchline Dec 17 '13 at 15:19
    
@Punchline OK, I think I understand. Give me a few minutes to write something useful. –  Mr.Wizard Dec 17 '13 at 15:24
    
Cool! It now works like it should - even though my coding skills need improving. Thanks –  Punchline Dec 17 '13 at 15:52
    
@Punchline You're welcome. –  Mr.Wizard Dec 17 '13 at 15:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.