パターン,規則,定義の評価
式の評価とパターンマッチングの処理では,いくつかの相互作用的な操作が必要になる.第一に,パターンマッチングでは,検索の対象となる式は少なくとも部分的に評価済みである.このため,パターン自体もあらかじめ評価しておいた方が都合がよい.
この例では,あらかじめパターンが評価される.このため,パターンは与えられた式にマッチする.
| Out[1]= |  |

条件の右辺は,パターンマッチングに使われるまで未評価のままにされる.
| Out[2]= |  |
場合によっては,パターンの全部もしくは一部を評価不可としておきたい.そうするには,HoldPatternを評価不可にしたい部分に作用させる.つまり,評価したくないパターンが patt ならば,HoldPattern[patt]と記述する.すると,パターンとしての patt の機能はそのまま保持されるが,パターン自体は未評価のままになる.
| HoldPattern[patt] | パターンマッチングの機能上は patt と同じだが,patt では評価は保留にする |
パターン評価の保留
HoldPatternの応用ケースとして,まだ評価されていない式,つまり未評価の形の式に対して適用するためのパターンの指定がある.
| Out[3]= |  |
注意してほしいのは,ホールドHoldのような関数を使うと式の評価を保留できるが,このような関数は,
や他の演算子を伴った式において,式の部分に対する操作には影響しないことである.
これは,

が引数を原子オブジェクトとしないときにその値を定義する.

のような式は条件に合わないので関数の定義は適用されない.
| Out[5]= |  |
しかし,パターン

は,

の定義に従って変換される.
| Out[6]= |  |
| Out[7]= |  |
上の例で示したように,通常,
のような変換規則において左辺 lhs はすぐに評価されてしまう.規則は,普通,すでに評価済みの式に対して適用されるからである.また,
における右辺もすぐに評価される.ただし,遅延型の規則
を使えば,右辺 rhs は評価しないまま保持しておくことができる.

による規則は直ちに評価されるが,

の規則は評価されない.
| Out[8]= |  |
両方の規則を適用したらどうなるか見てみよう.

規則の右辺は,未評価のまま
Hold式に組み込まれる.
| Out[9]= |  |
| lhs->rhs | 左辺 lhs と右辺 rhs をともに評価する |
| lhs:>rhs | 左辺 lhs は評価するが,右辺 rhs はしない |
変換規則における評価
変換規則の左辺は普通評価されるが,定義の左辺は普通評価されない.理由は次の通りである.変換規則は,通常,
を介して評価済みの式に適用される.これに対して,定義は評価の過程で適用される.つまり,まだ完全に評価の済んでいない式に適用される.定義をこのような式に対して適用可とするには,定義の左辺を少なくとも一部未評価のまま保持しておく必要がある.
最も単純なケースとして,シンボルに対する定義がある.「非標準な評価手順」で説明したが,
の定義において,左辺にあるシンボルは評価されないまま残される.もしも,定義が与えられる前に,x に y が割り当てられ,その上で,
により左辺が評価されることになったなら,
といったおかしな定義が発生してしまう.
| Out[10]= |  |
| Out[11]= |  |
左辺を強制的に評価する.すると,シンボル

ではなく,シンボル

の値である

が定義される.
| Out[12]= |  |

の値は

になっている.
| Out[13]= |  |
定義の左辺にある個々のシンボルは評価されないが,左辺が複雑な式からなるときは,それらが部分的に評価されることもある.例えば,左辺が
のような形を取るとき,引数部 args は前もって評価される.

はあらかじめ評価される.このため,値は

に対して定義される.
| Out[14]= |  |

に定義された値を確認する.
定義の左辺に現れる関数において,その引数部を先に評価しなければならない理由は,ある式の評価においてこの定義がどう使われるかを考えるとよく分かる.「評価の原理」で説明したように,関数が評価されるときは,関数の持つ引数がまず評価の対象になる.その次に,関数に関連した定義が検索され,見付かればそれが適用される.つまり,定義を関数に適用する前に,引数はすでに評価済みでなければならない.ただし,例外が1つある.それは,対象となる関数が特別な属性を備えており,引数の評価が保留になっているときである.
| symbol=value | 変数 symbol は評価しないが,値 value は評価する |
| symbol:=value | 変数 symbol と値 value はともに評価しない |
| f[args]=value | 引数 args は評価するが,左辺全体は評価しない |
| f[HoldPattern[arg]]=value | 引数 arg の評価なしで f[arg]が割り当てられる |
| Evaluate[lhs]=value | 左辺を完全に評価する |
定義における評価
定義の左辺に現れる関数において,その引数が先に評価されることは,普通,適切である.しかし,状況によっては,そうしたくない場合もある.そのようなときは,評価不可としたい部分に対してHoldPatternを作用させておく.