Почему чтение из памяти не побочный эффект, а чтение из файла?

16

Что именно делает чтение из памяти процесса чистой операцией? Предположим, я создал массив из 100 целых чисел в глобальной памяти, а затем взял 42-й элемент этого массива. Это не побочный эффект, верно? Так почему же чтение того же массива из 100 целых чисел из файла является побочным эффектом?

ZhekaKozlov
источник
5
рассмотрите возможность редактирования, чтобы объяснить, что заставляет вас думать, что чтение массива из 100 целых чисел из файла является побочным эффектом, а также что означает для вас «чистая операция»
gnat
3
@gnat Потому что это I / O, а I / O - побочный эффект
ЖекаКозлов
3
что заставляет вас думать, что ввод / вывод является побочным эффектом? рассмотрите возможность редактирования, чтобы объяснить это вопрос читателям. На более общей ноте, разделение вашего исследования помогает всем . Расскажите нам, что вы пробовали и почему это не соответствует вашим потребностям. Это свидетельствует о том, что вы потратили время, чтобы попытаться помочь себе, избавляет нас от повторения очевидных ответов и, прежде всего, помогает получить более конкретный и актуальный ответ. Также см. Как спросить
Гнат
22
@gnat I / O - это побочный эффект, точка. Это один из классических примеров. Мы не Википедия, нам не нужны цитаты для народных знаний. Если вы думаете, что что-то можно улучшить в этом вопросе, скажите это прямо, а не проходите через этого соломенного человека.
7
«О» является побочным эффектом. «Я» - это только побочный эффект, если выполнение «Я» меняет состояние того, из чего вы делаете «Я». Что верно для определенных операций ввода-вывода с отображением в памяти, но вряд ли будет иметь место для нормального файла.
Том Таннер

Ответы:

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-го элемента из глобальной памяти также будет побочным эффектом, если только ваш массив не является константой, поскольку это будет наблюдаемое взаимодействие с другими функциями, которые могут изменять массив.

stonemetal
источник
2

Если у вас есть дескриптор общего файла, то чтение файла переместит этот дескриптор файла в положение, в котором вы его прочитали, и оставит его в этой позиции.

Если у вас есть два потока с отдельными файловыми дескрипторами к одному и тому же файлу, чтение из одного не будет иметь заметных побочных эффектов для другого.

Однако в обоих случаях при чтении из памяти и при чтении файлов может быть скрытый побочный эффект кэширования операторской системы.

Дойная корова
источник
0

Чтение из памяти не влияет на другие функции и, следовательно, не имеет побочных эффектов. При чтении из файла обычно перемещается указатель позиции файла, поэтому при повторном чтении вы читаете данные после того, что уже прочитали, поэтому одна функция чтения изменяет результат других функций чтения, что является побочным эффектом. Если вместо этого вы открываете, читаете и закрываете файл за один раз, этот побочный эффект исчезает, но это невозможно для больших файлов. Кроме того, в зависимости от того, как вы открываете файл, он может заблокироваться после его открытия, поэтому первая попытка открыть и прочитать файл будет успешной, в то время как при следующих попытках произойдет сбой с ошибкой открытия файла , что снова является побочным эффектом.

Трудно создать функцию чтения без побочных эффектов, которая считывает файл за один раз и позволяет выполнять несколько операций чтения одновременно, поскольку существуют функции записи в файл, на которые влияет функция чтения, а избавление от функций записи в файл снова невозможно ,

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

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

Хаген фон Айцен
источник