2

私はこのコードラインをおもちゃの言語で使っています。 print -functionは引数のリストをとり、それらを出力します。私は、コールバイ値または電話バイ名を使用した場合名前で呼び出され、値で呼び出されると、これはどうなりますか?

print(a, (a := 5, a))

は出力に差があることでしょうか?もしそうなら、アウトプットはどうなるでしょう。

a0に初期化されていると考えることができます。 「値による呼び出し」引数を指定し

+2

'print'の実装に依存します – Bergi

+0

あなたの立場は何ですか?あなたは評価戦略のどの資料を読んでいますか、まだ不明な点は何ですか? – Bergi

+0

私はプロジェクトのコンパイラを書いていますが、誰かがコールバイア名前では '0 5'を、コールバイ値では' 5 5'を表示すると言ってくれました。彼の主張は、価値のあるコールの下では、最初にすべての表現を評価し、その後に結果を印刷することでした。これには真実はありますか? – Borimino

答えて

4

は、通常、(ほとんどの言語で)左から右に評価なので、式はこのようなものに相当します:「

arg1 := a // copy value of a to arg1 
a := 5 // copy 5 to a 
arg2 := a // copy value of a to arg2 
print(arg1, arg2) // print(0, 5) 

call-で、名前は」明らかに、このような何かを生じる遅延評価の形である:

arg1 := function() {return a;} 
arg2 := function() {a := 5; return a;} 
print(arg1, arg2) 

だからこのケースでは、結果は2つのことに依存します:

  • この言語では、参照または値でキャプチャ変数をクローズするかどうか。値でキャプチャする場合、a := 5は、最初のクロージャがキャプチャしたaの値には影響しません。しかし、ローカル変数の再割り当てを可能にするほとんどの言語は、参照によるキャプチャ(JavaScriptなど)を実装しています。
  • print関数が引数を評価することを決定する順序は、記述方法によって異なります。

クロージャ値でキャプチャする場合は割り当てa := 5だけaの第二の閉鎖のコピーに影響を与えるため、print(…)は、0 5を得られます。

クロージャが参照によって取得する場合、私は出力が何であるかを推測することしかできません。しかし、それはprint機能は、このような何かをします、非常に可能性があります:結果は(0 5)と同じになります

print := function(lazy x, lazy y) { 
    writeToOutput(x()) 
    writeToOutput(y()) 
} 

その場合には、x()が最初に評価されるため、処理結果、そしてy()が評価されます。この場合、xで機能が完了するまで、aの値は変更されません。

これは単なる推測です。 printは、任意の順序(任意の回数)で評価することができます。

+0

"引数は通常左から右(ほとんどの言語で)評価されます"注目すべきカウンタの例はC、C++、OCamlです。これらの言語では、関数の引数の評価順序は指定されていません(通常は右から左に実装されます)。 – sepp2k

+1

@ sepp2k:スキームとフレンド – rici

関連する問題