메모리에서 읽는 것이 부작용이 아니라 파일에서 읽는 이유는 무엇입니까?


16

프로세스 메모리에서 정확하게 읽기 작업을하는 것은 무엇입니까? 전역 메모리에 정수 100 개의 배열을 만든 다음이 배열의 42 번째 요소를 가져 갔다고 가정합니다. 부작용이 아닙니까? 그렇다면 왜 파일에서 100 개의 정수로 된 같은 배열을 읽는 것이 부작용입니까?


5
파일에서 100 개의 정수 배열을 읽는 것이 부작용이라고 생각하는 이유와 "순수한 조작"이 의미하는 바를 설명하는 편집을 고려 하십시오.
gnat

3
@gnat I / O이고 I / O는 부작용이기 때문에
ZhekaKozlov

3
I / O가 부작용이라고 생각하는 이유는 무엇입니까? 질문 독자들에게 설명하기 위해 편집 ] ing을 고려하십시오 . 좀 더 일반적으로, 연구를 공유하면 모든 사람들에게 도움이됩니다 . 당신이 무엇을 시도했고 왜 그것이 당신의 요구를 충족시키지 못했는지 알려주십시오. 이것은 당신이 시간을내어 자신을 돕기 위해 노력했고, 명백한 답변을 되풀이하는 것을 막아 주며, 무엇보다도 더 구체적이고 관련있는 답변을 얻는 데 도움이됩니다. 또한 물어
gnat

22
@gnat I / O는 부작용, 기간입니다. 고전적인 예 중 하나입니다. 우리는 Wikipedia가 아니며, 민속 지식에 대한 인용이 필요하지 않습니다. 질문에 대해 무언가 개선 될 수 있다고 생각되면이 밀짚 꾼을 거치지 말고 똑바로 말하십시오.

7
'O'는 부작용입니다. 'I'를 수행하면 'I'의 상태가 변경되는 경우 'I'는 부작용입니다. 어떤 메모리 매핑 된 I / O에 대해서는 사실이지만 일반 파일에서는 그렇지 않을 것입니다.
Tom Tanner

답변:


27

액세스하는 메모리가 변경 될 수 있으면 실제로 부작용입니다.

예를 들어, Haskell에서 가변 배열 ( IOArray) 에 액세스하는 함수의 유형은 다음과 같습니다.

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

(우리의 목적을 위해 약간 단순화). 불변 배열에 액세스하는 동안 유형이 있습니다

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

첫 번째 버전 IO e은 I / O 부작용이있는 유형의 무언가를 반환합니다 . 두 번째 버전은 e부작용없이 유형의 요소를 반환합니다 .

파일에 액세스하는 경우 프로그램 실행 중에 파일이 변경되는지 컴파일 타임에 알 수 없습니다. 따라서 항상 부작용이있는 작업으로 취급해야합니다.


4
파일이 있으면 절대 확실하지 않습니다.
ftr

2
확신 할 수는 없지만 더 중요한 것은 컴파일러가 확실하지 않다는 것입니다. 또한 파일을 읽는 동안 파일 시스템이 손상되거나 하드 디스크 연결이 끊어 질 수 있습니다.
Tobias Brandt

5
그것들은 프로그램의 부작용이 아니며, 다른 것들의 부작용입니다. 알파 입자 또는 스트레이 중성자가 비트를 뒤집어 배열에 변화를 줄 수 있기 때문에 메모리에는 부작용이 없습니다.
Blrfl

3
@Blrfl 좋은 지적이지만 두 사람이 비교할 수 있다고 생각하지 않습니다. 메모리 손상은 프로그램 데이터 및 명령에 임의의 방식으로 영향을 줄 수 있으므로 처리 할 수있는 것이 아닙니다. 이런 경우에는 프로그램 (및 아마도 OS)을 종료해야합니다. 반면에 파일 시스템 손상으로 인한 읽기 오류는 예상하고 처리 할 수있는 것입니다. 파일 처리의 본질적인 부분입니다.
Tobias Brandt

2
부작용의 영역에서 벗어나 오류 감지 및 처리에 빠져 있습니다. 이는 완전히 다른 토론입니다. 부작용 문제는 작업 결과가 외부 요인의 영향을받을 수 있는지 여부와 상관없이 작업이 다른 항목에 영향을 미치는지 여부 중 하나입니다.
Blrfl

10

컴퓨터 과학에서, 함수 또는 표현식은 값을 반환하는 것 외에도 일부 상태를 수정하거나 호출 함수 또는 외부 세계와 관찰 가능한 상호 작용을 갖는 경우 부작용이 있다고합니다. 파일에서 읽는 것은 외부 세계와의 관찰 가능한 상호 작용입니다. 부작용의 정의를 충족시킵니다. 배열이 수정 될 수있는 다른 함수와 관찰 가능한 상호 작용이기 때문에 배열이 상수가 아니면 전역 메모리에서 42 번째 요소를 읽는 것도 부작용이됩니다.


2

공유 파일 핸들이있는 경우 파일을 읽으면 해당 파일 핸들을 읽은 위치로 이동하고 해당 위치에 그대로 둡니다.

동일한 파일에 대해 별도의 파일 핸들이있는 두 개의 스레드가있는 경우 하나에서 읽는 것이 다른쪽에 눈에 띄는 부작용이 없습니다.

그러나 메모리 읽기와 파일 읽기 모두에서 운영자 시스템 캐싱의 숨겨진 부작용이있을 수 있습니다.


0

메모리에서 읽는 것은 다른 기능에 영향을 미치지 않으므로 부작용이 없습니다. 파일을 읽으면 일반적으로 파일의 위치 포인터가 이동하므로 다시 읽을 때 이미 읽은 내용을 읽은 후에 한 읽기 기능이 다른 읽기 기능의 결과를 변경하므로 부작용이 발생합니다. 대신에이 부작용이 사라지는 것보다 한 번에 파일을 읽고 닫으면 큰 파일에는 적용 할 수 없습니다. 또한 파일을 여는 방법에 따라 파일을 연 후 파일이 잠길 수 있으므로 파일 열기 및 읽기의 첫 번째 시도는 성공하지만 다음 시도는 파일 이미 열려 있음 오류 와 함께 실패하며 이는 부작용입니다.

한 번에 파일을 읽고 동시에 여러 번 읽을 수있는 부작용없는 읽기 기능을 만드는 것은 읽기 기능의 영향을받는 파일 쓰기 기능이 있고 파일 쓰기 기능을 다시 제거 할 수 없기 때문에 어렵습니다. .


1
파일이 변경되지 않고 파일을 스트림 (게으른 목록)으로 바꾸면 파일에서 부작용없이 읽을 수 있습니다.
Giorgio

2
당신의 통제하에 있지 않은 파일의 OS에 청하 이다 부작용. 파일의 가변성을 제어 할 수있는 경우 (그리고 IO모나드 를 통해 파일에서 시퀀스 돌연변이 작업을 수행 할 수있는 경우에만 ) 읽기를 위해 부작용없이 기능을 만들 수 있습니다.
Bergi

0

스트림에서 읽는 것은 이미 부작용이 있습니다. 왜냐하면 같은 함수의 결과 isEOF는 읽은 후와 읽은 것보다 다른 결과를 반환 할 수 있기 때문 입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.