差分

ナビゲーションに移動 検索に移動

正格評価

5,417 バイト追加, 2016年3月2日 (水) 05:25
モノブックでは、まだ成長していない項目を'''スタブ正格評価'''とよんでいます。たいていは、1段落程度の短さで、主題について十分に説明してありません。スタブはモノブックで調べ物をする人にとってあまり役に立ちません。ですから、スタブはきちんとした項目へと成長させなければなりません。ここでは、スタブをつくるときに心がけることと、スタブを成長させる方法について紹介します。とは、[[関数]]の[[引数]]が常にその関数に引き渡される前に完全に評価されることをいう。対義語は「[[遅延評価]]」である。 == 概要 ==正格な評価とは、[[関数]]や[[サブルーチン]]の[[引数]]が常にその関数に引き渡される前に完全に評価されることを意味する。むかしながらの多くの[[プログラミング言語]]は関数については正格な評価を行う。 [[チャーチ符号化]]においては[[演算子]]の[[先行評価]]は関数の正格な評価に写像される。そのため正格な評価は「先行評価」とも呼ばれる。 === 作用的順序 ===作用的順序の評価<ref name="sicp">訳は、[[計算機プログラムの構造と解釈]]より</ref>(applicative-order evaluation)は、もっぱら[[プログラミング言語]]よりは[[計算模型]]で使われる用語で、まず引数を全て評価し、それに関数をapply(作用、ないし適用)するという方法である。正規順序の評価(normal-order evaluation)の逆として対になっている。[[プログラミング言語]]における[[値呼び]]に同じとされることも多いが、英語版Wikipediaでは、関数の引数を左から右に[[木構造 (データ構造)|後順]]に走査して簡約可能な式を簡約していく評価戦略で「値呼びとは異なり、関数を作用させる以前に可能な限り関数本体内の項数を減らそうとする」ものとしている。 === 値呼び ===[[値呼び]](call by value、[[値渡し]]: pass by value)は多くの[[言語]]で採用されている典型的な評価戦略である。値呼びでは、関数呼び出しにある実引数を評価し、関数の仮引数を新しい変数としてその値に束縛し、しかる後に関数本体を実行する。関数の中で仮引数である変数に値を代入しても、それは局所的なコピーへの代入であり、呼び出した側の'''変数'''には影響しない。 [[手続き型言語]]ないし[[命令型言語]]では、[[演算子]]の左辺と右辺や、複数個並んだ引数の評価順が左から右であるか右から左であるかは、結果に違いを齎すことがあるが、仕様で決めている言語もあれば、決めていない言語もある。 === 参照呼び ===[[参照呼び]](call by reference、[[参照渡し]]: pass by reference)では、仮引数が実引数そのもの、すなわちエイリアスになる。実引数は左辺値を持たねばならない([[Pascal]]のように実引数を変数に限定した言語もある)か、左辺値を持たない式の場合は呼び出し側で一時的オブジェクトを構築する言語もある。 仮引数の変数は実引数のエイリアスであるから、それへの代入は呼び出した側の変数にも影響する。これを、[[ミュータブル]]な[[オブジェクト]]がある多くの言語において、オブジェクトへの「参照の値渡し」を行い、オブジェクトを変化させた場合に、呼び出した側から見てオブジェクトの変化が見えることと大変しばしば混同される。 関数の引数として参照を値渡しすることを参照渡しと呼ぶこともあり、[[C言語]]のように[[ポインタ]]を持つ言語では参照呼びではなく「アドレス呼び(call by address)」と呼ぶこともある、と考える者もいるようだが間違いである。[[C++]]ではなく[[C]]、[[Java]]、[[JavaScript]]などの値呼びしかない言語には参照呼びは無く、「それらの言語において似たように見えるもの」を「参照呼び」と呼ぶのは間違いである。間違った説明をネットに掲載したり、さらには書籍にまでする者が後を絶たず、非常に広範に流布しているが間違いである。C言語では、アドレス演算子 & により変数のアドレスを渡すことができるので、呼び先で元の変数の中身を変えてしまうことができるが、値呼びであることに変わりはない。 === Call by copy-restore ===Call by copy-restore(複製呼びの結果返し、などと意訳される)は、参照呼びの特殊な実装とも見ることができる。実引数の値が値呼びと同様にコピーされるが、関数呼び出しから戻る時に仮引数の変数の値が、あたかも参照呼びされたかのように書き戻される。 参照呼びと異なるのは、ある call by copy-restore の関数呼び出しの複数の引数に同じ変数を渡した場合、参照呼びでは、引数の1つを更新すると他の引数の内容も更新されるが、こちらでは、それぞれが異なるコピーであるため、他の引数の内容が更新されない。呼び出し側に戻ったときにどうなるかはそれぞれの仕様ないし実装による。 他にも、再帰呼び出しを行ったり、マルチスレッド環境で他のスレッドから観察されたりした場合には結果が異なってくる場合がある。 [[RPC]]などで、このようなふるまいが見られることがある。 === 部分評価 ===部分評価は評価戦略というよりは最適化手法である。部分評価では、適用されていない関数の本体内で評価が継続される。束縛されていない変数を含まない部分式は評価され、引数が既知の関数適用は簡約される。副作用があると、部分評価は予期しない結果を引き起こす可能性がある。このため、部分評価は関数内の副作用を持たない純粋な式についてのみ実施されることが多い。
== 関連項目 ==
* [[メインページ遅延評価]]* [[真正末尾再帰]] == 参考文献 =={{reflist}} {{stub}}
匿名利用者

案内メニュー