Block と Module の違い

Mathematicaにおいてもっともsubtleな点の一つではないか。

説明

  • Blockは既存の変数を書き換える。
  • Moduleは新しく変数を生成する。

x = y; y = 0; z = 2;と定義してあるとする。このとき、x を評価すると 0 になる。

Block[{y = 1, z}, {x, y, z}]

は {1, 1, 2} を返す。
Block内では、xは定義の右辺にあるyの定義が書き換えられて1になった状態で評価されるため1になる。zはクリアされ、zというシンボルのままBlockから出てくる。しかし、Blockの実行が終わるとzの定義は元の2に書き戻されるため、三番目の値は2になる。

Module[{y = 1, z}, {x, y, z}]

は、{0, 1, z$n} (n は 生成される毎に異なる整数) を返す。
このyはzと同様、毎回新しく生成される変数で、xの定義のyとは無関係だ。本来はy$mという名前なのだが、生成したModuleの中ではyでアクセスできるのだ*1

Module/Blockの共通点は、第一引数で定義された変数(y, z)の、ブロック(式の引数部分)内で直接使われた時(y, zと書いた時)の振舞は、外での同じ名前の変数の値に依存しないことだ。その意味ではどちらも局所変数の利用のために使うことができる式である。*2

Blockには外部の関数の定義を書き換えて使うことができるという強力さがある。

><

Moduleは誤って外部の定義を書き換えてしまう心配がない。

      • 単にブロック内に局所的な変数が欲しい場合にはこちらをつかう。

*3
*4

*1:名前を変えているだけであって、本当にローカルな変数なのではない。作られた変数は外でも使える

*2:上の例のリストの二要素目の値は1だ。zについては外にでたときに初めて違いが生じている

*3:つまり、Blockはダイナミックスコープの機能を実現する

*4:宿題に答えるのもなぁ