2016-11-30 7 views
7

私はモナスを使ってディスクI/Oのような副作用を追跡できるHaskellのような純粋な関数型言語の魅力を理解しています。副作用とは何か?なぜメモリ割り当てが副作用ではないのですか?

なぜすべてのシステムコールが副作用と考えられるのですか?たとえば、Haskellのヒープメモリ割り当て(自動)は追跡されません。そして、スタックの割り当ては副作用がありますが、それは役に立つとは思えません。どちらもシステムの全体的な状態を変更します。

したがって、副作用とは何のために描かれた線はどこですか?それは単に最も有用なものにありますか?あるいは、より理論的な基盤がありますか?

+6

私は、割り当てが副作用であった場合、非常に少ないものが「純粋」であり、そのようなものはコンセプトの有用性を低減するということです。純度には、1つの普遍的な厳密な定義がありません。私は、割り当てを副作用として扱い、少量のメモリ(組み込みシステム)を持つシステムで非常に有用な型システムを通してそれを管理する言語を想像することができましたが、私は何も知らないそのような言語は現在ありません。 –

+3

メモリ割り当ては、発生するタイミングを制御したい場合は副作用です。 IORef/STRef/FunPtrラッパーを参照してください。それが自動的に起こっている場合、コンパイラがそれについて賢明であると信じることができるので、Haskellはそれを心配するよう強制しません。 –

+0

@AlexisKing組み込みシステム用のコードを書かなければならないことがあります。私はそれがHaskellでDSLとして記述できると思いますが、非常に効率的にコンパイルされたスタンドアロン言語としてはクールです。 – bheklilr

答えて

11

これらのことを推論するときには、論理レベルと言語仕様レベルにある必要があり、ハードウェア上で実際にどのように行われるかは決してありません。

プログラミング言語は実際の実装ではありません。メモリの割り当てとsyscallを言語の一部として持つC og C++について考えない限り、これが部分的ではないシステムプリミティブによって処理される上位レベルの言語言語の言語の一部でない場合、それは副作用ではありません。

引数を渡して戻り値を受け取る方法は、どちらのレジスタまたはスタックにも格納されるため、実際の実装マシンコードは決して純粋ではありません。現代のプログラミングで使用するコンセプトのほとんどは、算術、フラグ、ジャンプ、メモリアクセスに変換されています。 NOPを除くすべてのCPU命令がマシンを変更します。 NOPのみで構成されるプログラムはあまり有用ではありません。

+1

良い答え、私はその実装とHaskellの仕様を混同したと思います。ありがとう。 割り当てのようなものに対して副作用セマンティクスを指定する言語のような低レベルのアセンブリ/ Cがあるのだろうかと思います。 – relevate

+2

CPU命令の評価にはハードウェアの実装も含まれているため、NOPは命令ポインタレジスタを変更することができます(同様に役に立たなくなります)。 –

+0

@thatotherguy Trueですが、NOP以外のすべての命令もプログラムカウンタ以外の何かを変更します。 – Sylwester

7

スタック割り当てもヒープ割り当ても、Haskellで "実行"することも、観測することもできません。したがって、副作用としてカウントすることはできません。ある意味では、純粋なHaskelコードを実行することは間違いなく認識可能な物理的効果であるが、CPUを加熱するためにも同じことが言えます。

現代のハードウェアとOS上のHaskellの特定の実装では、コードの実行中にスタック/ヒープが割り当てられますが、コードからは見えません。

+0

"現代のハードウェアやOS上のHaskellの特定の実装では、コードの実行中にスタック/ヒープが割り当てられます。 – jberryman

関連する問題