Short Version
The behaviour we see is by design. It is due to the fact that we are using the special head Evaluate
to force early evaluation of the second argument of CompoundExpression
-- an argument which would otherwise be held until its time came to be evaluated. If we wrap Identity
around Evaluate
, then this special action is prevented.
Details: A Simpler Case
We can see this behaviour using simpler expressions. First, consider the ordinary use of CompoundExpression
, whose shorthand operator form is ;
:
Print["one"]; Print["two"]
(* one
two *)
No surprises here. But if we wrap the second expression within Evaluate
, it is evaluated before the compound expression itself is evaluated:
Print["one"]; Evaluate[Print["two"]]
(* two
one *)
After that early evaluation and two is printed, the compound expression is effectively reduced to this:
Print["one"]; Null
(* one *)
Evaluate
is a distinguished head that has special meaning built into the evaluator. It causes its argument to be evaluated before the outer form itself, even though the outer form would otherwise hold the argument. CompoundExpression
is such a form because it has the HoldAll
attribute:
Attributes[CompoundExpression]
(* {HoldAll, Protected, ReadProtected} *)
The evaluation process is detailed in Power Programming with Mathematica by David B. Wagner. For the present case, see point 7(a) in section 7.1.3 on page 191.
Evaluate
is only meaningful if it is directly contained within an expression which holds its argument. Otherwise, it is essentially equivalent to Identity
. This is why the out-of-order evaluation is prevented if we wrap an explicit Identity
around Evaluate
:
Print["one"]; Identity[Evaluate[Print["two"]]]
(* one
two *)
Note how Evaluate
is no longer a top-level argument to CompoundExpression
.
Original Case From The Question
We can now see what happens in the Table
expression from the question:
setMyParameter[thisShouldNotAppear];
Table[(setMyParameter[p]; Evaluate[myParameter^2]), {p, {1, 2, 3}}]
(* {thisShouldNotAppear^2, 1, 4} *)
The presence of Evaluate
is causing myParameter^2
to be evaluated before setMyParameter[p]
. Thus, the results all appear to be "out by one" position.
A close inspection of the evaluation trace will show that the compound expression has already changed to setMyParameter[p];thisShouldNotAppear^2
prior to its first evaluation, and is setMyParameter[p];1
and setMyParameter[p];4
in the subsequent evaluations:
setMyParameter[thisShouldNotAppear];
TracePrint[Table[(setMyParameter[p]; Evaluate[myParameter^2]), {p, {1, 2, 3}}]]
(* large output omitted *)
The introduction of Identity
prevents this premature evaluation so we get the otherwise expected results:
setMyParameter[thisShouldNotAppear];
Table[(setMyParameter[p]; Identity[Evaluate[myParameter^2]]), {p, {1, 2, 3}}]
(* {1, 4, 9} *)
A simpler fix is to remove Evaluate
altogether as it is not needed here:
ClearAll[evaluateForThreeParameters, myParameter, setMyParameter];
setMyParameter[p_] := (myParameter = p);
evaluateForThreeParameters[form_] := Table[(setMyParameter[p]; form), {p, {1, 2, 3}}];
SetAttributes[evaluateForThreeParameters, HoldFirst];
setMyParameter[thisShouldNotAppear];
evaluateForThreeParameters[myParameter^2]
(* {1, 4, 9} *)