Чому читання з пам'яті не є побічним ефектом, а читання з файлу є?


16

Що саме робить читання з пам'яті процесу чистою операцією? Припустимо, я створив масив із 100 цілих чисел у глобальній пам'яті, а потім взяв 42-й елемент цього масиву. Це не побічний ефект, правда? То чому читає той самий масив із 100 цілих чисел з файлу побічним ефектом?


5
Розглянемо редагування ІНГ пояснити , що змушує вас думати , що читання масив з 100 цілих чисел з файлу є побічним ефектом, а також те , що робить «чисту операцію» означає для вас
комара

3
@gnat Тому що це I / O і I / O є побічним ефектом
ZhekaKozlov

3
що змушує вас думати, що введення / виведення є побічним ефектом? розгляньте редагування, щоб пояснити це питанням для читачів. Загалом, спільне дослідження допомагає всім . Розкажіть, що ви пробували і чому це не відповідало вашим потребам. Це свідчить про те, що ви знайшли час, щоб спробувати допомогти собі, це позбавляє нас від повторення очевидних відповідей, а найбільше це допомагає вам отримати більш конкретну та релевантну відповідь. Також дивіться Як просити
gnat

22
@gnat I / O - це побічний ефект, період. Це один із класичних прикладів. Ми не Вікіпедія, нам не потрібні цитати для народних знань. Якщо ви думаєте, що можна щось покращити у питанні, скажіть це прямо, а не переживаючи цього солом’яного чоловіка.

7
"O" - побічний ефект. "Я" є лише побічним ефектом, якщо виконання "Я" змінює стан того, що ви робите "Я". Це справедливо для певних речей пам'яті, відображених на вході / виводу, але навряд чи це стосується звичайного файлу.
Том Таннер

Відповіді:


27

Якщо пам'ять, до якої ви отримуєте доступ, може змінитися, то це справді побічний ефект.

Наприклад, у Haskell функція доступу до змінного масиву ( IOArray) має тип

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

(трохи спрощена для наших цілей). Під час доступу до незмінного масиву має тип

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

Перша версія повертає щось типу, IO eщо означає, що воно має побічні ефекти вводу / виводу. Друга версія просто повертає елемент типу eбез побічних ефектів.

У випадку доступу до файлу ви просто не можете знати під час компіляції, чи зміниться він коли-небудь під час запуску програми. Тому ви завжди повинні ставитися до цього як до операції з потенційними побічними ефектами.


4
Що ж, з файлами ви просто не можете бути абсолютно впевнені.
ftr

2
Ви ніколи не можете бути впевнені, але важливіше: компілятор не може бути впевнений. Крім того, ваша файлова система може пошкодитися або жорсткий диск може відключитися під час читання файлу.
Тобіас Брандт

5
Це не побічні ефекти програми, це побічні ефекти інших речей. Пам'ять також не є побічним ефектом, оскільки альфа-частинка або бродячий нейтрон можуть трохи перевернути і призвести до зміни масиву.
Blrfl

3
@Blrfl Це хороший момент, однак я не думаю, що обидва порівнянні. Пошкодження пам'яті - це не те, з чим можна боротися, оскільки це може впливати на програмні дані та інструкції довільно. Якщо це трапляється, єдине, що потрібно зробити, - це припинити програму (і, можливо, ОС). З іншого боку, помилка читання через пошкодження файлової системи - це те, чого потрібно очікувати та мати можливість впоратися. Це невід'ємна частина роботи з файлами.
Тобіас Брандт

2
Ви виходите з царини побічних ефектів і впадаєте у виявлення та поводження з помилками, що зовсім інша дискусія. Питання про побічні ефекти - це те, чи має операція якийсь вплив на щось інше, не залежно від того, чи можуть на результат операції впливати чи ні зовнішні фактори.
Blrfl

10

В інформатиці, функція або вираз мають побічний ефект, якщо крім повернення значення, він також змінює деякий стан або має помітну взаємодію з функціями виклику або зовнішнім світом. Читання з файлу - це помітна взаємодія із зовнішнім світом. Він відповідає визначенню побічної дії. Читання 42-го елемента з глобальної пам'яті також буде побічним ефектом, якщо тільки ваш масив не є постійним, оскільки це буде спостережувана взаємодія з іншими функціями, які можуть змінювати масив.


2

Якщо у вас є спільна ручка файлу, то читання файлу перемістить цю ручку файлу у положення, де ви прочитали, і залишить її в цьому положенні.

Якщо у вас є два потоки з окремими ручками файлів до одного файлу, читання з одного не матиме помітного побічного ефекту для іншого.

Однак в обох цих випадках читання пам'яті та читання файлів може бути прихованим побічним ефектом кешування системи оператора.


0

Читання з пам’яті не впливає на інші функції, тому не має побічних ефектів. Читання з файлу, як правило, переміщує покажчик положення файлу, так що при повторному читанні ви читаєте дані після того, що ви вже прочитали, тому одна функція читання змінює результат інших функцій читання, що є побічним ефектом. Якщо замість цього відкрити, прочитати та закрити файл за один раз, цей побічний ефект зникає, але для великих файлів це неможливо. Крім того, залежно від того, як ви відкриєте файл, він може бути заблокований після його відкриття, тому перша спроба відкрити і прочитати файл успішно, а наступні спроби не вдасться, коли файл вже відкритий , що знову ж таки є побічним ефектом.

Створити функцію читання без побічних ефектів, яка читає файл за один раз і дозволяє одночасно читати кілька разів, важко, оскільки є функції запису файлів, на які впливає функція читання, і позбутися функцій запису файлів знову не представляється можливим. .


1
У вас може виникнути побічне читання з файлу, якщо файл не змінився, і ви перетворили файл у потік (лінивий список).
Джорджіо

2
Звернення до ОС за файлом, який не знаходиться під вашим контролем, є побічним ефектом. Тільки якби ви могли керувати мутаційністю файлу (а може, операціями, що мутують послідовність на ньому… через IOмонаду?), Ви могли б зробити функцію, що не має побічних ефектів для читання.
Бергі

0

Читання з потоку є побічним ефектом вже тому, що результат таких функцій, як isEOFможе, повертає інший результат після прочитаного, ніж перед прочитаним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.