なぜメモリからの読み取りは副作用ではなく、ファイルからの読み取りが副作用なのですか?


16

プロセスメモリからの読み取りを純粋な操作とするのは何ですか?グローバルメモリに100個の整数の配列を作成し、この配列の42番目の要素を取得したとします。副作用ではありませんよね?では、なぜファイルから100個の整数の同じ配列を読み取るのが副作用なのでしょうか?


5
考える編集をあなたに平均「純粋な操作」何あなたがファイルから100個の整数の配列を読んだことは副作用であると思わせる何かを説明するINGのと同様に、
ブヨ

3
@gnat I / Oであり、I / Oは副作用であるため
ZhekaKozlov 14年

3
I / Oが副作用だと思う理由は何ですか?編集を検討して、読者に質問することを説明してください。より一般的な注意事項として、研究を共有することは全員に役立ちます。試したことと、それがニーズに合わなかった理由を教えてください。これは、あなたが時間をかけて自分自身を助けようとしていることを示しており、明白な答えを繰り返すことから私たちを救い、何よりも、より具体的で関連性のある答えを得るのに役立ちます。参照してください掲載する方法
GNAT

22
@gnat I / Oは副作用であり、期間です。これは古典的な例の1つです。私たちはウィキペディアではありません。民俗知識のための引用は必要ありません。質問について何か改善できると思うなら、このストローマンを通り抜けるよりも、あからさまに言ってください。

7
「O」は副作用です。「I」を実行すると、「I」の実行状態が変更された場合にのみ、「I」は副作用になります。これは、特定のメモリマップI / Oに当てはまりますが、通常のファイルには当てはまりません。
トム・タナー

回答:


27

アクセスするメモリが変更される可能性がある場合、それは実際に副作用です。

たとえば、Haskellでは、可変配列(IOArray)にアクセスする関数の型は

Ix i => IOArray i e -> i -> IO e

(私たちの目的のために少し簡略化されています)。不変配列にアクセスしている間は型があります

Ix i => Array i e -> i -> e

最初のバージョンIO eは、I / O副作用があることを意味するタイプの何かを返します。2番目のバージョンは、e副作用のないタイプの要素を単に返します。

ファイルにアクセスする場合、プログラムの実行中にファイルが変更されるかどうかをコンパイル時に知ることはできません。したがって、潜在的な副作用を伴う操作として常に扱う必要があります。


4
さて、ファイルを使用すると、単に確実に確認することはできません。
ftr 14年

2
決して確信することはできませんが、より重要なのは、コンパイラーが確信できないことです。さらに、ファイルの読み取り中にファイルシステムが破損したり、ハードディスクが切断されたりする場合があります。
トバイアスブラント14年

5
これらはプログラムの副作用ではなく、他のものの副作用です。メモリも副作用がないわけではありません。アルファ粒子または漂遊中性子が少し反転し、配列が変化する可能性があるためです。
Blrfl 14年

3
@Blrflそれは良い点ですが、この2つが比較できるとは思いません。メモリ破損は、プログラムのデータと命令に任意の方法で影響を与える可能性があるため、対処できるものではありません。発生した場合、プログラム(およびおそらくOS)を終了するだけです。一方、ファイルシステムの破損による読み取りエラーは、予期して処理できる必要があるものです。これは、ファイルの処理に固有の部分です。
トバイアスブラント14年

2
副作用の領域から抜け出し、エラーの検出と処理に取り掛かります。これはまったく異なる議論です。副作用の問題は、操作の結果が外部要因によって影響を受けるかどうかではなく、操作が他の何かに影響を与えるかどうかの1つです。
Blrfl 14年

10

コンピューターサイエンスでは、関数または式は、値を返すことに加えて、状態を変更したり、呼び出し元の関数または外部世界と観察可能な相互作用がある場合、副作用があると言われています。 ファイルからの読み取りは、外界との観察可能な相互作用です。副作用の定義を満たします。グローバルメモリから42番目の要素を読み取ることは、配列が定数である場合を除き、副作用でもあります。これは、配列を変更する可能性のある他の関数との相互作用であるためです。


2

共有ファイルハンドルがある場合、ファイルを読み取ると、そのファイルハンドルが読み取った位置に移動し、その位置に残ります。

同じファイルへの個別のファイルハンドルを持つ2つのスレッドがある場合、一方からの読み取りは、もう一方への顕著な副作用はありません。

ただし、メモリ読み取りとファイル読み取りのどちらの場合でも、オペレーターシステムのキャッシュの隠れた副作用が生じる可能性があります。


0

メモリからの読み取りは他の機能に影響を与えないため、副作用はありません。通常、ファイルから読み取ると、ファイルの位置ポインターが移動します。そのため、再度読み取ると、すでに読み取ったデータの後にデータが読み取られるため、1つの読み取り関数が他の読み取り関数の結果を変更します。これは副作用です。代わりに、この副作用が消えるよりも、一度にファイルを開いたり、読んだり閉じたりすると、大きなファイルには実行できません。さらに、ファイルを開く方法によっては、ファイルを開いた後にロックされる可能性があるため、最初のファイルを開いて読み取ろうとすると成功しますが、次の試行はファイルが既に開いていますエラーで失敗しますが、これも副作用です。

ファイルを一度に読み取り、同時に複数の読み取りを可能にする副作用のない読み取り関数を作成することは、読み取り関数の影響を受けるファイル書き込み関数があり、ファイル書き込み関数を取り除くことが再び不可能であるため、困難です。


1
ファイルが変更されず、ファイルをストリーム(遅延リスト)に変更した場合、ファイルから副作用のない読み取りを行うことができます。
ジョルジオ14年

2
管理下にないファイルをOSにリーチする、副作用が生じます。ファイルの可変性を制御できる場合にのみ(そして、おそらくIOモナドを介してファイルのシーケンス変更操作を行うことができますか?)、読み取り用の副作用のない関数を作成できます。
ベルギ

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