コンテンツにスキップ

「評価戦略」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
m ref style
編集の要約なし
30行目: 30行目:


=== 参照の値渡し ===

=== 参照の値渡し ===

参照の値渡し (共有呼び: call by sharing、オブジェクト呼び: call by object、call by object-sharing) は [[:en:Barbara Liskov|Barbara Liskov]] 他によって19274年に[[CLU]]言語で最初に call by sharing と呼ばれた評価戦略である。<ref name="CLU Reference Manual">[http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-225.pdf CLU Reference Manual]</ref> 日本語では参照の値渡し<ref>[https://magazine.rubyist.net/articles/0032/0032-CallByValueAndCallByReference.html 値渡しと参照渡しの違いを理解する]</ref>とも呼ばれる。[[Python]]、Iota、[[Java]]、[[Ruby]]、[[JavaScript]]、[[Scheme]]、[[OCaml]]、[[AppleScript]]等の多数の言語で使われている。しかしながら「参照の値渡し」という用語は一般的では無く、異なる情報源間で用語の混乱が見られる。例えば、Javaの分野ではJavaは全て値渡しであると言われている。参照の値渡しは、言語上の値が[[プリミティブ型]]ではなく[[オブジェクト_(プログラミング)|オブジェクト]]に基づいているということ、つまり全ての値が「[[ボックス化]]」されていることを意味している。

参照の値渡し (共有呼び: call by sharing、オブジェクト呼び: call by object、call by object-sharing) は [[:en:Barbara Liskov|Barbara Liskov]] 他によって1974年に[[CLU]]言語で最初に call by sharing と呼ばれた評価戦略である。<ref name="CLU Reference Manual">[http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-225.pdf CLU Reference Manual]</ref> 日本語では参照の値渡し<ref>[https://magazine.rubyist.net/articles/0032/0032-CallByValueAndCallByReference.html 値渡しと参照渡しの違いを理解する]</ref>とも呼ばれる。[[Python]]、Iota、[[Java]]、[[Ruby]]、[[JavaScript]]、[[Scheme]]、[[OCaml]]、[[AppleScript]]等の多数の言語で使われている。しかしながら「参照の値渡し」という用語は一般的では無く、異なる情報源間で用語の混乱が見られる。例えば、Javaの分野ではJavaは全て値渡しであると言われている。参照の値渡しは、言語上の値が[[プリミティブ型]]ではなく[[オブジェクト_(プログラミング)|オブジェクト]]に基づいているということ、つまり全ての値が「[[ボックス化]]」されていることを意味している。



参照の値渡しの意味論は参照渡しとは異なる: "In particular it is not call by value because mutations of arguments performed by the called routine will be visible to the caller. And it is not call by reference because access is not given to the variables of the caller, but merely to certain objects"{{Sfnp|CLU Reference Manual|1974|p=14-15}}(意訳「とりわけ、呼び出し先で行われた引数に対する変更は呼び出し元からも見えるため、値渡しではない。また、アクセスは呼び出し元の変数ではなく、単にあるオブジェクトに対して行われるため、参照渡しでもない。」) だから、例えば、変数が渡されたとき、呼び出し先のスコープ内で変数への代入を装うことは不可能である。ただし、関数は呼び出し元と同じオブジェクト(コピーされたものではない)にアクセスできるため、オブジェクトが可変([[ミュータブル]])であれば、関数内でのオブジェクトへの変更は呼び出し元にも反映される。これは値渡しの意味論とは異なる動作である。オブジェクトはコピーでもクローンでもない、つまり共有されているから、関数内での可変オブジェクトへの変更は、呼び出し元からも見えると言うことである。例として、配列(Array)が可変であるRubyで書くと:

参照の値渡しの意味論は参照渡しとは異なる: "In particular it is not call by value because mutations of arguments performed by the called routine will be visible to the caller. And it is not call by reference because access is not given to the variables of the caller, but merely to certain objects"{{Sfnp|CLU Reference Manual|1974|p=14-15}}(意訳「とりわけ、呼び出し先で行われた引数に対する変更は呼び出し元からも見えるため、値渡しではない。また、アクセスは呼び出し元の変数ではなく、単にあるオブジェクトに対して行われるため、参照渡しでもない。」) だから、例えば、変数が渡されたとき、呼び出し先のスコープ内で変数への代入を装うことは不可能である。ただし、関数は呼び出し元と同じオブジェクト(コピーされたものではない)にアクセスできるため、オブジェクトが可変([[ミュータブル]])であれば、関数内でのオブジェクトへの変更は呼び出し元にも反映される。これは値渡しの意味論とは異なる動作である。オブジェクトはコピーでもクローンでもない、つまり共有されているから、関数内での可変オブジェクトへの変更は、呼び出し元からも見えると言うことである。例として、配列(Array)が可変であるRubyで書くと:


2019年8月19日 (月) 04:12時点における版


: evaluation strategy




reduction(1) (2) (X Y) XY使

 (strict)  (non-strict) 

C++

if






[1]applicative-order evaluation使applynormal-order evaluationWikipedia


call by value: pass by value



call by reference: pass by referenceAliasingPascal


 (: call by sharing: call by objectcall by object-sharing)  Barbara Liskov 1974CLU call by sharing [2] [3]PythonIotaJavaRubyJavaScriptSchemeOCamlAppleScript使JavaJava

: "In particular it is not call by value because mutations of arguments performed by the called routine will be visible to the caller. And it is not call by reference because access is not given to the variables of the caller, but merely to certain objects"[4]() ()()(Array)Ruby:
def f(arr)
  arr.append(1)
end

m = []
f(m)
p m

これは [1] を出力する。なぜなら、appendメソッドは呼び出されたオブジェクトを変更しているからだ。

これらの言語では、変数を渡すことは、変数によって参照される実際のオブジェクト渡す(アクセスする)事を意味しており、オリジナルの(呼び出し元の)変数にアクセする事では意味しているわけでは無いため、関数内での代入は呼び出し元に影響を与えない。再束縛された変数(仮引数となる変数)は関数内にしか存在しないため、呼び出しと元の対応する変数(実引数となる変数)は元の束縛を維持する。上記のRubyでの変更の動作と新しいオブジェクトを引数に代入する次のコードを比較してみると:

def f(arr)
  arr = [1]
end

m = []
f(m)
p m

 [] arr = [1] ()

()(input/output parameters): ()()

Python(call by sharing)Ruby()使JavaVisual Basic

Call by copy-restore


Call by copy-restore

 call by copy-restore 1



 (RPC) 

部分評価




使

使


[1]normal-order evaluation使Wikipedia


call by name: pass by nameCapture-Avoiding Substitution使使使

使使

ALGOL 60 

Jensen's Device 


call by need pass by need使



Haskell


call by macro expansion使使Hygienic


Haskell2
multiply x y = x * y
twice x = multiply x 2

となる。部分適用されているのはtwiceを定義している'multiply x 2'の部分である。multiply関数は本来なら

multiply 2 3

使2twice 使

β-


β-full β-reduction使


call by futureparallel call by name使使


Optimistic Evaluation1調

  1. ^ a b 訳は、計算機プログラムの構造と解釈より
  2. ^ CLU Reference Manual
  3. ^ 値渡しと参照渡しの違いを理解する
  4. ^ CLU Reference Manual (1974), p. 14-15.

関連項目

参考文献