Message Boards Message Boards

0
|
6694 Views
|
2 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Understand the standard evaluation chain on global variables?

Posted 6 years ago

I don't understand the behaviour of the following:

test0[x_, y_] := Module[
   {},
   a = 2*x;
   Return[y]
   ];

test1[] := Module[
   {},
   a
   ];

Now I run this little programms:

In[168]:= Remove["a"]
test0[1, test1[]]
test0[2, test1[]]
test0[3, test1[]]

Out[169]= 2

Out[170]= 2

Out[171]= 4

If "a" ist not defined, "a" will be evaluated in bevor calling test1[], but if "a" has already a value then "a" is evaluated after calling test1[]. How can I force that "a" ist always evaluated before?

POSTED BY: Juerg Baertsch
2 Replies
Posted 6 years ago

Thank you very much, Unevaluated[] is exactly what I was lookin for.

That the function in the argument ist evaluatet first, was logical for me. I was only confused, because I thought that then the first output must be the symbol "a" and not 2. My wrong conclusion was, that in this case (when a has no value) the argument is evaluated later. But I see now, that this is wrong. Its evaluated to the symbol "a" and so the "a=2*x" works.

Thanks again for solving my confusion ;)

POSTED BY: Juerg Baertsch

You are mistaken and this is an excellent question to understand a small portion of the "Main Evaluation" that happens in every single Mathematica call. Let's start with a very simple expression

Print[1+1]

Why do you think Mathematica prints 2 and not 1+1, because this is what I told it to do? The answer is that the standard evaluation chain (read: the function does not handle its arguments in a special way), Mathematica always evaluates the arguments of a function before it calls the function. This means here that first 1+1 is evaluated to 2 and then Print[2] is called.

Now look at your example and you understand easily, that you are searching your error in the wrong place. Let us assume, you have called your first line test0[..] then a has a value of 2. Now, apply the same rule I described above to the line

test0[2, test1[]]

What do you think happens if before test0 is even called, its arguments and especially test1[] is evaluated. Do you see, that test1[] does evaluate to 2? Therefore, your Return line just gives the constant value 2 and not the result of calling test1. The third result works the same way but in the meantime, you have assigned a new value to a.

To solve this, you have to force Mathematica to keep your test1 argument unevaluated

test0[1, Unevaluated[test1[]]]
test0[2, Unevaluated[test1[]]]
test0[3, Unevaluated[test1[]]]
POSTED BY: Patrick Scheibe
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract