Haskellの値/参照セマンティクスのテストの考案


8

命令型言語では、言語の「値のセマンティクス」または「参照のセマンティクス」の使用に関するプログラミングテストを考案することは簡単です。次のようにしてa(where Vertex {one, two, three :: Integer})の値を確認できます。

a := Vertex 3 4 5
b := a
one b   :=  6
two b   :=  8
three b := 10

ただし、関数型言語では変数は不変であるため、このテストはそのような言語では機能しません。

私はHaskell(および関数型プログラミング全般)についてほとんど知りませんが、私の理解では、値のセマンティクスを使用しています。Haskellで「refレコード」と「valレコード」を区別するプログラミング実験を考案することは可能ですか?


1
二文目は、a「の値をチェックする」という意味ですか?


Haskellは参照透過的です。[1]つまり、Haskell では「値のセマンティクス」と「参照のセマンティクス」は同等です。[1]プログラミング言語オタクはそのステートメントについて長い議論を交わしますが、私がしたような意味でそれを使用することは非常に伝統的です。
ジョナサンキャスト

回答:


9

このようなテストはありません。なぜなら、可変性がないと、区別は意味がないためです(説明したとおり)。


3
これは、Haskellの(の一部ことは注目に値するIORefMVarなど)を参照(として変更可能と振る舞いですhpaste.org/81192
ダニエルGratzer

9

Haskellには参照がありません(参照は変更可能なオブジェクトであり、Haskellには(直接アクセス可能な)変更可能なオブジェクトがありません)。したがって、関数呼び出しは、デフォルトのような値のセマンティクスを使用します。これは実際、純粋な関数型言語の重要な特性です。関数は引数を変更できません。

値のセマンティクスは、コピーが内部で行われることを意味しませ。関数が変更する値の一部のみをコピーする必要があります。つまり、純粋な言語では、何もコピーする必要はありません。

ただし、これだけではありません。ある意味で、Haskellには参照セマンティクスがあります。

関数が引数を変更するかどうかをテストすることは意味がありません(変更しないかどうか)が、関数がその引数(の一部)を使用するかどうかをテストできます。終了しない引数を指定してください。関数呼び出しが終了すると、関数が引数を使用しなかったことがわかります。

let bottom = bottom
let ignore x = 1
ignore bottom

あなたが評価した場合bottom、それは終了しません:bottomそれ自体に展開し、悪心。用語にbottom値を含めることはできません。しかし、あなたが評価ignore bottomした場合、その値は1です。これは、関数を呼び出すときにignore引数の値を計算する必要がないことを示しています。この意味で、Haskellには参照セマンティクスがあります。関数が受け取るのは値ではなく、この値を見つけることができるものです。技術用語は、名前による呼び出しです値による呼び出しではありません)。

(より正確には、Haskell実装はcall by needを使用します。callby valueでは、関数の引数は関数を呼び出す直前に1回だけ評価されます。callby nameでは、引数は使用されるたびに評価されます。関数の必要な回数だけ実行されます。必要に応じた呼び出しでは、引数は最大で1回評価されます。最初に使用されたときに評価されます。使用されていない場合は評価されません。)


2
もちろん、純粋な言語では、必要な呼び出しと名前による呼び出しは区別できません。その後、必要に応じて呼び出すだけで最適化戦略になります。
イェルクWミッターク

2
@JörgWMittag良い点、私はそれを言及するのを忘れていました。(ちなみに、簡単に言うと、有限メモリで動作している場合、call-by-needは常にcall-by-nameの方が効率的ではありません。)
Gilles 'SO- stop be evil'

1
ええ、でも、記憶が有限なのは誰ですか?私たちは皆チューリングマシンを使用していますよね?真剣に:それはあなたがあなたが値を「必要とする」かどうかに関するある簿記のオーバーヘッドのためであると思いますよね?例えばサンクやそのような何か?
イェルクWミッターク

3
@JörgWMittagしかし、Turingマシンであっても、メモリは制限であり、より多くのものを保持している場合、有用なものに到達するには、テープをより多く往復する必要があります。実際のコンピュータでは、これは貧弱なキャッシュの局所性と呼ばれます。
Gilles「SO-邪悪なことをやめなさい」

7

それらを区別することは不可能です。これが意味することは、コンパイラーは、最適なパフォーマンスに適合すると思われるセマンティクスを使用することを自由に選択できるということです。

特に、関数型言語は、それらの概念モデルと一致するため、通常値のセマンティクスを持つものとして記述されますが、より効率的であるため、参照セマンティクスを使用して実装されることがよくあります。(変更できないものをコピーする必要はありません!)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.