Plot using With versus Plot using Block (Mathematica)?

Your question is not so much about Plot as it is about how the scoping constructs work. The main confusion here is due to the differences between lexical and dynamic scoping. And the main culprit is this definition: fx_ := (vmax x)/(km + x) The problem with it is that it makes f implicitly depend on the global symbols (variables) vmax and km I am very much against this sort of constructs since they lead to infinite confusion.

Now, what happens can be illustrated with the following example: In55:= With{vmax =1, km = 2},fx Out55= (vmax x)/(km+x) To understand why this happens, one must understand what the lexical scoping means. We know that With has a HoldAll attribute. The way it works is that it looks are what is literally inside it, and substitutes variables found literally in the body with their values from the declaration list.

This happens during the variable-binding stage, and only then it lets the body to evaluate. From this, it is clear that the following will work: In56:= With{vmax =1, km = 2},Evaluatefx Out56= x/(2+x) This worked because Evaluate overrides the "part" of HoldAll attribute of With forcing the body to evaluate before anything else (variable binding, and subsequent body evaluation). Therefore, it would be completely equivalent to use just With{vmax = 1, km = 2}, (vmax x)/(km + x) above, as you can see with Trace The next part of the puzzle is why With{vmax = 10, km = 10}, PlotEvaluate@fx, {x, 0, 100}, AxesOrigin -> {0, 0} does not work.

This is because this time we do not evaluate the body first. The presence of Evaluate affects only fx inside Plot but not the evaluation of Plot itself inside With This is illustrated by In59:= With{vmax = 10, km = 10}, qEvaluate@fx Out59= q(vmax x)/(km + x) Moreover, we do not want Plot to evaluate first, since then the values of vmax and km will not be defined. However, all that With sees is fx and since the parameters vmax and km are not literally present in there (lexical scoping, remember), no substitution will be made.

Should we use Block here, and things will work, because Block uses dynamic scoping, meaning that it redefines values in time (part of the execution stack if you wish), rather than in place. Therefore, using Block{a =1, be =2}, ffx where ff implicitly depends on a and be is (roughly) equivalent to a=1;b=2;ffx (with the difference that a and be resume their global values after the Block scope is left). So In60:= Block{vmax = 10, km = 10}, qEvaluate@fx Out60= q(10 x)/(10 + x) To make the With version work, you'd have to inject the expression for fx (r.h.

S), for example like so: In63:= UnevaluatedWith{vmax = 10, km = 10}, qfx /. DownValuesf Out63= q(10 x)/(10 + x) Note that this won't work: In62:= With{fx = fx}, With{vmax = 10, km = 10}, qfx Out62= q(vmax x)/(km + x) But the reason here is quite subtle: while outer With evaluates before the inner one, it spots the variable name conflicts and renames its variables. Rules are much more disruptive, they don't respect inner scoping constructs EDIT If one insists on nested With s, here is how one can fool the name conflict resolution mechanism of With and make it work: In69:= With{fx = fx}, With @@ Hold{vmax = 10, km = 10}, qfx Out69= q(10 x)/(10 + x) Since outer With can no longer detect the presence of inner With (using ApplyWith,Hold... makes the inner With effectively dynamically generated), it does not make any renamings, and then it works.

This is a general trick to fool lexical scoping name resolution mechanism when you don't want renaming, although the necessity to use it usually indicates a bad design END EDIT But I digressed. To summarize, making your second method work is quite hard and requires really weird constructs like Unevaluated With{vmax = 10, km = 10}, PlotEvaluate@fx, {x, 0, 100}, AxesOrigin -> {0, 0} /. DownValuesf or.

Your question is not so much about Plot as it is about how the scoping constructs work. The main confusion here is due to the differences between lexical and dynamic scoping. And the main culprit is this definition: fx_ := (vmax x)/(km + x) The problem with it is that it makes f implicitly depend on the global symbols (variables) vmax and km.

I am very much against this sort of constructs since they lead to infinite confusion. Now, what happens can be illustrated with the following example: In55:= With{vmax =1, km = 2},fx Out55= (vmax x)/(km+x) To understand why this happens, one must understand what the lexical scoping means. We know that With has a HoldAll attribute.

The way it works is that it looks are what is literally inside it, and substitutes variables found literally in the body with their values from the declaration list. This happens during the variable-binding stage, and only then it lets the body to evaluate. From this, it is clear that the following will work: In56:= With{vmax =1, km = 2},Evaluatefx Out56= x/(2+x) This worked because Evaluate overrides the "part" of HoldAll attribute of With, forcing the body to evaluate before anything else (variable binding, and subsequent body evaluation).

Therefore, it would be completely equivalent to use just With{vmax = 1, km = 2}, (vmax x)/(km + x) above, as you can see with Trace. The next part of the puzzle is why With{vmax = 10, km = 10}, PlotEvaluate@fx, {x, 0, 100}, AxesOrigin -> {0, 0} does not work. This is because this time we do not evaluate the body first.

The presence of Evaluate affects only fx inside Plot, but not the evaluation of Plot itself inside With. This is illustrated by In59:= With{vmax = 10, km = 10}, qEvaluate@fx Out59= q(vmax x)/(km + x) Moreover, we do not want Plot to evaluate first, since then the values of vmax and km will not be defined. However, all that With sees is fx, and since the parameters vmax and km are not literally present in there (lexical scoping, remember), no substitution will be made.

Should we use Block here, and things will work, because Block uses dynamic scoping, meaning that it redefines values in time (part of the execution stack if you wish), rather than in place. Therefore, using Block{a =1, be =2}, ffx where ff implicitly depends on a and be is (roughly) equivalent to a=1;b=2;ffx (with the difference that a and be resume their global values after the Block scope is left). So, In60:= Block{vmax = 10, km = 10}, qEvaluate@fx Out60= q(10 x)/(10 + x) To make the With version work, you'd have to inject the expression for fx (r.h.

S), for example like so: In63:= UnevaluatedWith{vmax = 10, km = 10}, qfx /. DownValuesf Out63= q(10 x)/(10 + x) Note that this won't work: In62:= With{fx = fx}, With{vmax = 10, km = 10}, qfx Out62= q(vmax x)/(km + x) But the reason here is quite subtle: while outer With evaluates before the inner one, it spots the variable name conflicts and renames its variables. Rules are much more disruptive, they don't respect inner scoping constructs.

EDIT If one insists on nested With-s, here is how one can fool the name conflict resolution mechanism of With and make it work: In69:= With{fx = fx}, With @@ Hold{vmax = 10, km = 10}, qfx Out69= q(10 x)/(10 + x) Since outer With can no longer detect the presence of inner With (using ApplyWith,Hold... makes the inner With effectively dynamically generated), it does not make any renamings, and then it works. This is a general trick to fool lexical scoping name resolution mechanism when you don't want renaming, although the necessity to use it usually indicates a bad design. END EDIT But I digressed.To summarize, making your second method work is quite hard and requires really weird constructs like Unevaluated With{vmax = 10, km = 10}, PlotEvaluate@fx, {x, 0, 100}, AxesOrigin -> {0, 0} /.

DownValuesf or With{fx = fx}, With @@ Hold{vmax = 10, km = 10}, PlotEvaluate@fx, {x, 0, 100}, AxesOrigin -> {0, 0} Once again: all this is because With must "see" the variables explicitly in the code, to make replacements. In contrast, Block does not need that, it replaces values dynamically at the moment of evaluation, based on their modified global values, as if you made assignments, this is why it works. Now, the real culprit is your definition of f.

You could have avoided all these troubles should you have defined your f with explicit parameter-passing: ffx_, vmax_, km_ := (vmax x)/(km + x) Now, this works out of the box: With{vmax = 10, km = 10}, PlotEvaluate@ffx, vmax, km, {x, 0, 100}, AxesOrigin -> {0, 0} because the parameters are explicitly present in the function call signature, and so are visible to With. To summarize: what you observed is a consequence of the interplay between lexical and dynamic scoping. Lexical scoping constructs must "see" their variables explicitly in the code at the variable-binding stage (before evaluation), or they won't be effective.

Dynamic scoping effectively modifies values of symbols, and is in this sense less demanding (the price you pay is that the code using lots of dynamic scoping is harder to understand, since it mixes state and behavior). The main reason for trouble is the function definition that makes implicit dependencies on global symbols (that are not in the formal parameter list of the function). It is best to avoid such constructs.

It is still possible to make things work, but this is considerably more complicated (as was demonstrated above), and, at least for the case at hand, for no good reason.

2 Another excellent post Leonid. – Mr.Wizard Jun 4 at 15:42 2 +1 for another Nice Answer, which it is indeed – belisarius Jun 4 at 17:15 @Mr.Wizard, @belisarius Thanks! – Leonid Shifrin Jun 4 at 18:04 3 Thanks, Leonid.

There is lots to learn from your answer. – David Carraher Jun 4 at 22:37 @Leonid. That is a great explanation.

A lot of things have become clearer. Your examples have explained a lot, and your advise on function definition has simplified things quite a bit. Many, many thanks – TomD Jun 4 at 23:22.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions