# Tag Info

126

You will find a lot of information in this answer. I will add a few personal notes. Module Use Module when you want to localize variables inside your functions body, and those variables will potentially acquire and/or change their values during the computation. Basic use For example: f[x_]:=Module[{y=x^2},y=y+x;{x,y}] Here, a local mutable variable ...

45

I don't think one can avoid the need for nested With altogether - I find it a very common case to need declared variables use previously declared variables. Since I once wrote the function (actually macro) that automates nesting With, and generates nested With at run-time, this is a good opportunity to (re)post it as an answer to an exact question that it ...

37

Safety Module is safer than Block because: It is a lexical scoping construct, which means that variable bindings are only tied to a specific piece of code. Variables outside that piece of code are never affected by these bindings. In contrast, Block basically binds a variable to a piece of execution stack, not a piece of code. Such bindings are much ...

34

The differences between Module, Block and With are nicely summarized by the results of the following expressions: x = "global"; f[] := x Module[{x = "local"}, {x, f[], Hold[x]}] Block[{x = "local"}, {x, f[], Hold[x]}] With[{x = "local"}, {x, f[], Hold[x]}] which returns: {"local", "global", Hold[x$123]} (* Module *) {"local", "local", ... 34 InternalInheritedBlock (IIB) is similar to Block, except that it preserves the original definition of the function being passed to it. The function can then be modified as we wish inside the IIB without affecting the external definition. Let's see how Block works first: f[x_] := x Block[{f}, Print@DownValues[f]; f[x_, y_] := x y; ... 28 I'll cover a few typical uses of Block, neither of which is possible using Module or With. Temporarily removing definitions When you do Block[ {a = x}, ... ] the original definition of a is effectively replaced by whatever new definition is given in the first argument of Block, for the duration of the evaluation of Block only. If we give no ... 27 Scoping constructs, lexical scoping and variable renamings It pays off to understand a bit deeper how the scoping constructs work and what happens behind the scenes when you execute one. In addition to the documentation, this was discussed in part here, but let us present some summary. When the lexical scoping construct Sc[vars, body] executes (where Sc ... 24 Here is the almost obligatory timing response, it probably doesn't generalise very broadly but perhaps is indicative in some respects: (* no variables *) f1[x_] := (x^2; x^3;) f2[x_] := Module[{}, x^2; x^3;] f3[x_] := Block[{}, x^2; x^3;] f4[x_] := With[{}, x^2; x^3;] (* With variable definition *) f2[x_] := Module[{y = 0}, x^2; x^3;] f3[x_] := Block[{y = ... 22 With works by performing a substitution operation prior to executing its body, and likely it is only a single pass. So, inter-referencing the variables is not possible. Since With accepts the use of SetDelayed (:=), you might think that that could be used, instead. For example, With[{v1 = #, v2 := f[v1]}, g[v1, v2]]& @ p (* g[p, f[v1]] *) which ... 22 InternalLocalizedBlock behaves the same as Block, but it can localize non-Symbols (e.g. f[1], Subscript[x, 0], etc.). For example, InternalLocalizedBlock[{Subscript[x, 0]}, Subscript[x, 0] = 1] (* 1 *) Compare this to Block[{Subscript[x, 0]}, Subscript[x, 0] = 1] (* During evaluation of In[79]:= Block::lvsym: Local variable specification ... 19 I will leave the explanation of the difference between lexical and dynamic to those more qualified than myself (and to the documentation). One practical difference between Block and Module is this: Module[{x}, x] Block[{x}, x] (* -> x$1979 x *) That is, if you construct something inside a Block with a blocked variable and then return it, you may use ...

19

In V10 -- Needs["GeneralUtilities"]; ?GeneralUtilitiesWhere Where[ass1, ass2, ..., expr] is a version of With that supports multiple sequential assignments. Needs["GeneralUtilities"]; Where[v1 = #, v2 = f[v1], g[v1, v2]] (* g[#1, f[#1]] *) Where[x = 2, t = x^2, Hold[x + t]] (* Hold[2 + 4] *)

18

For a single code statement, this is probably an overkill. If you have two or more of them, you have to group them in any case. CompoundExpression is one obvious choice, such as f[x_]:= ( Print[x]; x^2 ) Instead, you could also do f[x_]:= Module[{}, Print[x]; x^2 ] which is what I personally often prefer. Apart from some ...

18

There will no doubt be plenty of answers for this one. However the short answer is: Use With for local constants that you don't have to change subsequently. Use Module for local variables that are local to that piece of code. Use Block for local variables that are local to that sequence of evaluation. This tutorial in the Mathematica documentation ...

17

Based on Mr.Wizard's answer and comments by Szabolcs and celtschk, I now understand that the code I posted does have undesirable side-effects and it should be avoided. Specifically, the scoping constructs Module and Block are meant to completely localize the variables in their first argument (for more information see this question). However, placing their ...

16

I think that this has been discussed many many times before, but it keeps popping up. So, I will state this once again: Do not allow functions' bodies to depend on symbols not passed to them explicitly If you follow this simple principle, you will be guaranteed that you will not see this sort of surprises. Here is a link to the detailed discussion on this ...

16

What's happening This is not simple by any means. You have encountered another instance of a general situation with lexical scope leaks / emulation / over-protection by symbol renaming. The case at hand is pretty similar to the one discussed here, so you can read the detailed explanation of this behavior in my answer there. Roughly speaking, outer lexical ...

15

As a point of curiosity, I did a quick search in the source code used by Wolfram for various palettes, dialog boxes, and toolbars. About one in eight Dynamic constructs were accompanied by a With. The example you provide is certainly a good one. It illustrates the general principle nicely, but what it doesn't do is to illustrate how widely the general ...

15

You cannot make definitions with patterns on the left-hand side in the first argument of a scoping construct (such as Module). You need do that in the body of the Module. You should also use a different symbol for the internal function parameter. norm[x_] := Module[{fun1, fun2}, fun1[p_] := p^2 + p - 1; fun2[p_] := p^3 - p^2 + p + 1; ...

15

What happens and why As Daniel Lichtblau pointed out in comments, this behavior can also be viewed as a flaw in the current behavior / design / implementation of lexical scoping in Mathematica. However, it may be useful still to understand on a deeper level what happens, since it can be explained rather easily from the core rules of how lexical scoping ...

14

This might work as you expect and be save even if definitions for x exist: Block[{x}, f[x_] = D[Sin[x], x];] I would strongly suggest that you get familiar with Derivative and pure functions if you work with symbolic derivatives, though. This will make your life much easier in the long term. Your example would reduce to: f = Derivative[1][Sin] and a ...

14

You just have to wrap the Module around those variables, to make them semi-local: Module[{persistent}, persistent := persistent = Import["path\\file"]; SomeFunction[date_,column_]:= (body using persistent); getPce[date_,column_] := Module[{dates, value, b, e}, value = SomeFunction[...]; ] ] Here we ...

14

In your notebook, do the following: Separate the examples into cell groups. You can use, e.g., Section or Subsection cells to do this. Choose the menu item Evaluation->Notebook's Default Context->Unique to Each Cell Group. Re-evaluate your notebook. You'll now get the code isolation you're looking for. By using the menu item I point out, you're ...

14

If you look at the generated code (CompilePrint, for example), the procedure is as follows: All the program's constants are placed into separate registers (regardless of their location in the program, they can be in the r.h.s.of variable initialization in scoping constructs, or they can be statements in their bodies. Actually, same constants found in ...

13

Briefly, Block allows you to temporarily change global definitions and functions in a way that Module does not. This is both its strength and weakness. If you use Block[{x = 5}, (* stuff *)] without realizing that something deep inside "stuff" relies on x you may break things. On the other hand you can use this power intentionally to do some interesting ...

13

This is as designed (as it should be). In general, when you use Block[{s = someExpression}, body] then s is initialized with the value of someExpression, computed using the surrounding environment (usually Global context). But then, all changes made to the properties of s, remain local to Block and are undone after the execution exits Block. In the ...

12

With allows definition of local constants. An example (that I recently posted as an answer) would have been a good candidate for this: a regular expresion. With[{regex = RegularExpression[...]}, If[... something with regex ...]; If[... something else with regex ...] ] Other uses would be if you need to precalculate a local constant (Sin[20°] etc) ...

12

I think this should be OK Module[{x, expr}, expr = 2 x; Function @@ {x, expr} ] (because {x,2*expr} gets evaluated before Function replaces the List head)

12

To avoid those scoping constructs being recognized as such and having their variables renamed, I like wrapping their heads with Identity. In your case, func[opt_] := Identity[With][{a = True}, "x" /. opt]

11

Try this: g = 4.49*^3; m = 1.; s = 1.; ϵ = 2.; With[{g = g, m = m, s = s, ϵ = ϵ}, sAcceleration = Compile[{{sPosition, _Real, 1}}, (-g (m + s))/(sPosition.sPosition + ϵ*ϵ)^(3/2) sPosition]; sAcceleration2 = Compile[{{sPosition, _Real, 1}}, Module[{gg = g, mm = m, ss = s, ϵϵ = ϵ^2}, (-gg (mm + ss))/(sPosition.sPosition + ϵ)^(3/2) sPosition]]; ...

Only top voted, non community-wiki answers of a minimum length are eligible