Wolfram: Local Variable
Block
. (dynamic scope)Module
. (lexical scope)With
. (local constants)
Block. (dynamic scope)
Block[{var1, var2, etc}, body]
-
- Eval body with temp local values of variables.
- Each of the variable var can be the form
var = val
or you can set the value in the body. - Return the value of body.
When the body is more than one expression, add semicolon between them. γsee CompoundExpression and Semicolonγ
Variable chaining works. The latter variable's value expression sees the previous variable's value. e.g., in
Block[{x = 2, y = x}, y]
y has a value of 2.π WARNING: If a variable in body has no value inside
Block
, its global value is used. If it has no global value, its value is the symbol itself.π WARNING: If any expression in body evaluates to an expression that contains a symbol name and name is one of the declared variable, it takes the local value. e.g.
y = x; Block[ {x=3}, x+y] === 6
π‘ TIP: when using
Block
, make sure all the local variables declared in it is unique globally, as much as possible. e.g.Block[ {xxalpha127=3, yyradius862=4}, body]
(* basic example *) Block[{x, y}, x = 3; y = 4; x+y] == 7 (* True *) Block[{x = 3, y = 4}, x+y] == 7 (* True *)
(* variable chaining *) Block[{x = 2, y = x}, y] (* 2 *) Block[{x = 2, y = x, z = y}, z] (* 2 *)
(* if a variable has no value inside Block, its global value is used *) x = 3; Block[{x}, x] (* 3 *) (* if a variable has no value inside Block, and no global value, it is treated as a symbol *) Block[{y}, y] (* y *)
(* leaked x *) y = x; Block[ {x=3}, x+y] (* 6 *) (* tip. use unique names to avoid collision *) y = x; Block[ {xx=3}, xx+y] (* 3 + x *)
Module (lexical scope)
Module
is like Block
, but lexical scope,
and is significantly slower.
Module[{var1, var2, etc}, body]
-
- Eval body with temp local variables.
- Each of the variable var can be the form
var = val
or you can set the value in the body. - Return the value of body.
When the body is more than one expression, add semicolon between them. γsee CompoundExpression and Semicolonγ
π WARNING: No variable chaining. The latter variable's value expression does not know the previous variable's value. e.g., in
Module[{x = 2, y = x}, y]
, y has a value of symbol x, not 2. To assign variable that depends on previous variable value, assign them in the body.Any variable names declared in
Module
are internally replaced by a unique symbol of the formname$n
, to prevent collision with any names outside of it.π‘ TIP: This is similar to βlexical scopedβ construct in most programing languages.
(* basic example of Module *) Module[{x, y}, x = 3; y = 4; x+y] == 7 (* True *) Module[{x = 3, y = 4}, x+y] == 7 (* True *)
(* to assign variable that depends on previous variable value, put the assignment in body. i recommend this form *) Module[{x, y}, x=2; y=x; y] == 2 (* True *)
(* demonstrate local variable value of Module *) x = 5; Module[{x}, x = 3; x+1] == 4 (* True *) x == 5 (* True *) (* x is still 5 *)
(* No variable chaining *) Module[{x=2, y=x}, y] === x (* True *)
(* demonstrate that names declared inside Module are generated anew, so no relation to any names outside of it *) x = 3; Module[{x,y}, {x,y}] (* {x$1539, y$1539} *)
With. (local constants)
With
, is similar to Module
, except the variables must have a value and cannot be changed.
With[{c1 = v1, c2 = v2, etc}, body]
-
- Eval body with temp local constants.
- Return the value of body.
π WARNING: No variable chaining. The latter constant's value expression does not know the previous constant's value. Example:
With[{x = 2, y = x}, y] === x
With[{x = 3}, x+1] == 4
y = x; With[ {x=3}, x+y] (* 3 + x *) (* lexical scope. the y does not become 3 *)
π‘ TIP: When to use Block, Module, With
Block
is fast. Just make sure all the local variables declared in it is unique globally.
Use With
for good functional programing practice.
One issue is that it does not allow variable chaining, so it means you will need to nest it if you have variables that depends on previous variables.
Module
is the most safe in variable collision problem.
But is slowest, because it renames all local variables with new unique names.