Mathematica 9 is now available
THIS IS DOCUMENTATION FOR AN OBSOLETE PRODUCT.
SEE THE DOCUMENTATION CENTER FOR THE LATEST INFORMATION.
Mathematica >

即時的な定義と遅延的な定義

Mathematicaで割当てを行うには,2つの違った方法があることに読者はすでに気が付いているかもしれない.つまり,lhs=rhslhs:=rhsである.これらの形の間にある基本的な違いは,いつ式rhs が評価されるかにある.lhs=rhsは即時型の割当てを表し,右辺rhs は定義した時点で評価される.これに対して,lhs:=rhs は遅延型の割当てを表し,rhs は,割当てが行われるときには評価されず,lhs の値が要求されるときに毎回評価される.
lhs=rhs (即時型の割当て) 右辺rhs は,定義時に評価される
lhs:=rhs (遅廷型の割当て)右辺rhs は,左辺lhs の値が要求されるときに毎回評価される

2種類の割当て

演算子:=を使い関数exを定義する.
In[1]:=
Click for copyable input
:=を使ったので,定義は未評価のまま維持される.
演算子=で割当てを行うと,右辺は即座に評価される.
In[3]:=
Click for copyable input
Out[3]=
ここで保存された定義は,Expandコマンドの結果である.
exが実行されるときに初めてExpandの操作が行われる.
In[5]:=
Click for copyable input
Out[5]=
iexは,その引数を展開済みの式に代入し,exとは違った答を返す.
In[6]:=
Click for copyable input
Out[6]=
上の例から分かるように,=:=はともに関数を定義する上で便利だが,違った意味を持っている.このため,状況に応じて使い分ける必要がある.
使い分けの目安として次の手順を取るとよい.割当てを,ある式の最終的な「値」を与えるものととらえるならば,演算子=を使う.また,割当てを,値を見出すための「コマンド」としてとらえるならば,演算子:=を使う.どちらかはっきりしないときは,通常,=ではなく,:=を使うと無難である.
lhs=rhs右辺rhs は,左辺lhs の「最終値」(例:f[x_]=1-x^2
lhs:=rhsrhs は, lhs の値が要求されるときに実行される「コマンド」や「プログラム」を与える(例:f[x_]:=Expand[1-x^2]

演算子=:=による割当て操作の解釈

関数の定義でおそらく,:=は,=より多く使われるだろうが,次に示す重要な場合には,必ず=を使い関数を定義しなければならない.ある計算を行い,シンボル的パラメータx により答が得られるとき,x を各種の特定値としたときに結果がどうなるかを調べる必要がよく出てくる.そのようなときは,ひとつの方法として,演算子/.を使い,x について適切な規則を適用することが考えられる.しかし,通常は,=を使い,引数をx とした関数を定義した方がより便利になる.
xに依存した式を作る.
In[7]:=
Click for copyable input
Out[7]=
名前をxとした値の引数を取る関数を定義する.
In[8]:=
Click for copyable input
Out[8]=
これは,x1+aとしたときの結果である.
In[9]:=
Click for copyable input
Out[9]=
上の例において重要な点は,パターンx_に現れる名前xは特別な意味を持たないということである.他の任意の式に現れるxと同様に,単なるシンボルでしかない.
f[x_]=exprx が特定値を取るときに値expr を返す関数を定義する

式を評価するための関数の定義

=:=は,関数定義だけでなく変数への値の割当てにも使うことができる.x=value と入力すれば,値value は即座に評価され,結果はx に割り当てられる.一方,x:=value と入力すると,value はすぐには評価されない.入力されたままの形で維持され,実際に,x が使われるときに毎回再評価される.
これは,RandomReal[]を評価し,得られた擬似乱数をr1に割り当てる.
In[10]:=
Click for copyable input
Out[10]=
RandomReal[]は未評価のまま維持され,r2が実際に参照されるときに毎回再評価される.
In[11]:=
Click for copyable input
r1r2の値を調べる.
In[12]:=
Click for copyable input
Out[12]=
r1の値は変わらない.しかし,r2が使われると,その都度,新たな乱数が生成される.
In[13]:=
Click for copyable input
Out[13]=
数珠つなぎに割当て関係を構築していく際は,即時型の割当てと遅延型の割当ての間にある違いは,特に重要である.
a1とする定義を行う.
In[14]:=
Click for copyable input
Out[14]=
a+2が評価され,結果3riの値として割り当てられる.
In[15]:=
Click for copyable input
Out[15]=
a+2は評価されないまま保持される.rdの値が要求されると,そのたびに再評価される.
In[16]:=
Click for copyable input
値を確認する.この時点で,rirdは同じである.
In[17]:=
Click for copyable input
Out[17]=
aの値を変える.
In[18]:=
Click for copyable input
Out[18]=
rdには新たなaの値が使われるが,riは古い値のままである.
In[19]:=
Click for copyable input
Out[19]=
t:=rhs の遅延型の割当てを使えば,変化する「状況」に応じた値を右辺rhs に割り当てることができる.t を参照するときは,その都度,それが依存するオブジェクトの最新値が使われて右辺rhs が再評価される.
遅延型の割当て式の右辺は未評価のまま保持される.
In[20]:=
Click for copyable input
a4を割り当てたときのtの値を求める.
In[21]:=
Click for copyable input
Out[21]=
aを6にするとどうだろうか.
In[22]:=
Click for copyable input
Out[22]=
上の例で,シンボルatの値を左右する「大域変数」として働く.パラメータをたくさん使う必要があり,また,それらの値をあまり変える必要がなければ,この割当て方法は便利でよいだろう.しかし,変数が他の変数への隠された依存性を持つようなときは,この方法で変数の割当てを行うとかえって混乱させるかもしれないので注意が必要である.関数を定義する際に,必要なすべてのパラメータを引数とすることで,依存性を明示化しておいた方がよい.
lhs->rhs右辺rhs は規則の定義時に評価される
lhs:>rhs右辺rhs は規則が使われるときに評価される

2種類の変換規則

割当てに,即座に行うものと,後で行うものの2種類があるように,変換規則にも即時型と遅延型がある.
関係式の右辺は即座に計算される.
In[23]:=
Click for copyable input
Out[23]=
このような規則は実用的な価値がないが,入力してみる.
In[24]:=
Click for copyable input
Out[24]=
規則の右辺は未評価の形のまま保持される.規則が使われるときに毎回評価される.
In[25]:=
Click for copyable input
Out[25]=
この規則を適用させると,初めて右辺の式が展開される.
In[26]:=
Click for copyable input
Out[26]=
割当ての場合と同じように,置換する値が確定しているときは,->を使うようにし,また,式の値を求めるためのコマンドを与えるときには,:>を使うようにする.
Ask a question about this page  |  Suggest an improvement  |  Leave a message for the team