「すべてがオブジェクトです」、オブジェクト参照にアクセスできない言語(例: JavaおよびScalaの場合、すべての関数パラメータは、言語より下の抽象レベルで渡される参照です。しかし、言語抽象化のセマンティクスの観点からは、関数が参照されたオブジェクトのコピーを提供されているかどうかによって、参照による呼び出しまたは値による呼び出しがあります。この場合、共有による呼び出しという用語には、抽象化の言語レベルでの参照による呼び出しと値による呼び出しの両方が含まれています。したがって、Javaは、言語セマンティクスよりも抽象度が低い(つまり仮想マシンの場合はCまたはバイトコードに変換される方法と比較して)抽象度の高い値で呼び出され、JavaおよびScalaは、 "すべてがオブジェクトです"という抽象概念のセマンティクスで参照渡し(組み込み型を除く)です。
JavaおよびScalaでは、組み込み型(a/k/aプリミティブ)の型は自動的に値渡し(intまたはIntなど)され、すべてのユーザー定義型が渡されます(つまり、彼らは彼らの価値だけを渡す)。
注これをより明確にするために、WikipediaのCall-by-sharing sectionを更新しました。
おそらく、ウィキペディアは、値渡しと呼び出しによる呼び出しの区別について混乱しているのでしょうか?代入式や関数の適用に適用されるように、値渡しがより一般的な用語であると私は考えました。私はWikipediaでその訂正をしようとする気にはならなかった。
オブジェクトが不変の場合、参照によるコールと値渡しの間に「すべてがオブジェクトです」というセマンティクスのレベルに違いはありません。したがって、値による呼び出しと参照による呼び出しの宣言を可能にする言語(私が開発しているScalaのような言語のような)は、オブジェクトが変更されるまで値のコピーを遅らせることによって最適化することができます。
これを明らかに投票した人々は、「共有による呼び出し」が何であるか分かりません。
以下、評価戦略について議論している私のCopute言語(JVMをターゲットにしています)の書き込みを追加します。
純粋であっても、チューリング完全言語再帰を可能にする)は、評価戦略を選択しなければならないため、完全に宣言的です。評価戦略は、関数とその引数の間の相対的なランタイム評価順序です。関数の評価戦略は、すべての式が関数であるため、それぞれ厳密または怠惰と同じ厳密または非厳密にすることができます。 Eagerは、関数の前に引数式が評価されることを意味します。 lazyは引数の式が関数内での最初の使用の実行時にのみ評価されることを意味します。 評価戦略は、パフォーマンス、決定論、デバッグ、およびオペレーショナルセマンティクスのトレードオフを決定します。純粋なプログラムの場合、評価順序の不可欠な副作用は、メモリ消費、実行時間、待ち時間、および非終端ドメインで非決定性を引き起こす(すなわち、断定的に限定される)ため、意味的セマンティクスの結果を変更しません。入力が1つの純粋な関数であり、バイナリ演算子は2つの入力を持つ純粋な関数であり、コンストラクタは関数であり、さらには制御文でもあります(例えば、)。 if、for、while)を関数でモデル化することができます。これらの関数を評価する順序は、構文では定義されていません。 f(g())はgの結果をfに評価することができ、fの中でその結果が必要なときにlをゆっくりと評価することができる。
前者(eager)はコールバイバリュー(CBV)であり、後者(lazy)はcall-by-name(CBN)です。 CBVには、Java、Python、Rubyなどの現代的なOOP言語で広く使われている、別の呼び出しごとのバリアントがあります。 CBNには、関数の引数が一度しか評価されない(関数をメモする関数と同じではない)バリアントコールバイニング(CBN)もあります。指数関数的に高速であるため、コールバイニングは名前の代わりにほとんど常に使用されます。通常、CBNの両方のバリアントは、宣言された関数階層と実行時の評価順序の間の不協和音のために純粋にしか現れません。
言語には通常、デフォルトの評価方法があり、一部にはオプションで、デフォルト以外の機能で評価されるように強制するための構文があります。デフォルトで熱望している言語は、通常、第2オペランドが第2オペランドではないため、論理演算子(a/k/a "と" & &)と論理和(a/k/a "または"、||場合の半分に必要な、すなわち真実||何か==真と偽& &何か== false。
私は、あなたがScalaで価値のあるデータ構造を渡すことはできないと思いました。 – Gabe
@Gabeこれはまだ[値渡し/通話]です(http://en.wikipedia.org/wiki/Evaluation_strategy)(AnyRefの型の値渡しの値渡しのオブジェクト参照とPython/Javaの人々はこれを「参照渡し」という言葉を悪用するのが好きです。しかし、pass/by-by-referenceは、関数*で変数*を設定すると渡された変数の値を設定することを意味します(VBではC++では '&ref'、VBでは' ByRef'、C#では 'out/ref') 。これは渡されたオブジェクトと状態の突然変異で*エミュレートされますが、同じではありません(Cはポインタで参照される値を変更することでCをエミュレートできます)。 –
@pst:私は「メソッドに膨大なデータ構造を渡す」部分を参照していました。 Scalaには、データ構造を関数に渡すときにデータ構造をコピーすることを知らされていなかったか、またはデータ構造がすでに参照渡しされていて、OPからの引用は無関係です。 – Gabe