부작용의 개념을 명확하게 이해하지 못했습니다.
- 프로그래밍의 부작용은 무엇입니까?
- 프로그래밍 언어에 의존합니까?
- 외부 및 내부 부작용과 같은 것이 있습니까?
부작용을 일으키는 원인의 예를 제시하십시오.
답변
부작용은 국가의 어떤 종류의 수정 단순히 의미 – 예를 들면 :
- 변수 값 변경
- 디스크에 일부 데이터 쓰기;
- 사용자 인터페이스에서 버튼 활성화 또는 비활성화
일부 사람들의 말과 달리 :
-
부작용 않습니다 하지 숨길 수 또는 예상치 못한이 (가 될 수 있지만 그것이 컴퓨터 과학에 적용되는 정의와는 아무 상관이 없습니다)
-
부작용은 dem 등원과 관련 이 없습니다 . dem 등원 기능에는 부작용이있을 수 있으며 비등 전성 기능에는 부작용이 없을 수 있습니다 (예 : 현재 시스템 날짜 및 시간 가져 오기).
정말 간단합니다. 부작용 = 어딘가에 무언가를 바꾸는 것.
PS 주석가 벤졸이 지적한 바와 같이, 몇몇 사람들은 부작용 정의를 순수한 기능 의 정의 와 (a) dem 등원 및 (b) 부작용이없는 기능인 것과 동일시 할 수있다 . 하나는 일반적인 컴퓨터 과학에서 다른 하나를 의미하지는 않지만 기능적 프로그래밍 언어는 일반적으로 두 가지 제약 조건을 모두 적용하는 경향이 있습니다.
답변
컴퓨터의 상태를 수정하거나 외부 세계와 상호 작용하는 모든 작업은 부작용이 있다고합니다. 부작용 에 대한 Wikipedia를 참조하십시오 .
예를 들어이 기능에는 부작용이 없습니다. 결과는 입력 인수에만 의존하며 프로그램 상태 또는 호출 될 때 환경이 변경되지는 않습니다.
int square(int x) { return x * x; }
반대로,이 함수를 호출하면 컴퓨터 상태에 따라 변경되기 때문에 호출 순서에 따라 다른 결과를 얻을 수 있습니다.
int n = 0;
int next_n() { return n++; }
void set_n(int newN) { n = newN; }
이 함수는 출력에 데이터를 쓰는 부작용이 있습니다. 반환 값을 원하기 때문에 함수를 호출하지 않습니다. “외부 세계”에 미치는 영향을 원하기 때문에이를 호출합니다.
int Write(const char* s) { return printf("Output: %s\n", s); }
답변
기존 답변이 상당히 좋다고 생각합니다. IMO에 스트레스가 충분하지 않은 몇 가지 측면을 자세히 설명하고 싶습니다.
수학에서 함수는 튜플 값에서 값으로의 매핑입니다. 그래서, 함수 주어진 f
과 값 x
, f(x)
항상 같은 결과가 될 것입니다 y
. 당신은 잘 대체 할 수 f(x)
와 y
식 도처에서 아무것도 변경됩니다.
많은 프로그래밍 언어에서 함수 (또는 프로 시저)는 다음과 같은 이유로 실행될 수있는 구성 (코드 조각)입니다.
- 수학적 의미로 함수를 계산합니다. 즉, 주어진 입력 값, 결과를 반환합니다. 또는
- 예를 들어 화면에 무언가를 인쇄하고, 데이터베이스의 값을 변경하고, 미사일을 발사하고, 10 초 동안 잠을 자고, SMS를 보내는 등의 효과가 있습니다.
따라서 효과는 상태뿐만 아니라 미사일 발사 또는 몇 초 동안 실행 일시 중지와 같은 다른 측면과 관련 될 수 있습니다.
부작용이라는 용어는 부정적으로 들릴 수 있지만 일반적으로 함수 호출의 효과는 함수 자체의 목적입니다. I 용어 함수 원래 수학에서 사용 된 이후의 값을 계산하는 것은로 간주한다는 가정 차 효과 다른 영향이 고려되는 반면 함수의 부작용 . 일부 프로그래밍 언어는 프로 시저 라는 용어를 사용 하여 수학적인 의미에서 함수와 혼동을 피합니다.
참고
- 일부 절차는 반환 값과 부작용에 모두 유용합니다.
- 일부 프로시 저는 결과 값만 계산하며 다른 효과는 없습니다. 수학 함수에서 함수를 계산하기 만하면되기 때문에 종종 순수 함수라고합니다.
sleep()
파이썬 과 같은 일부 절차 는 부작용에 대해서만 유용합니다. 이것들은 종종 특별한 값을 반환하는 함수로 모델링None
되거나unit
또는()
또는 … 또는 단순히 계산이 올바르게 종료되었음을 나타내는 함수로 모델링 됩니다.
답변
부작용은 작업이 의도 된 용도를 벗어난 변수 / 객체에 영향을 미치는 경우입니다.
전역 변수를 변경하는 부작용이있는 복잡한 함수를 호출하면 호출 한 이유가 아니더라도 데이터베이스에서 무언가를 추출하기 위해 호출했을 수 있습니다.
나는 완전히 고안되지 않은 간단한 예제를 생각해내는 데 어려움을 겪고 있으며, 내가 작업 한 것들의 예제는 여기에 게시하기에는 너무 길다 (그리고 관련 작업이므로 어쨌든해서는 안된다) ).
내가 본 한 예는 (연결이 닫힌 상태 인 경우) 데이터베이스 연결을 여는 기능이었습니다. 문제는 함수의 끝에서 연결을 닫아야한다는 것이었지만 개발자는 해당 코드를 추가하는 것을 잊었습니다. 따라서 여기에는 의도하지 않은 부작용 이있었습니다 . 프로 시저를 호출하면 쿼리 만 수행해야하고 부작용은 연결이 열린 상태로 유지되고 함수가 두 번 연속 호출되면 연결이 발생했다는 오류가 발생합니다. 이미 열려 있습니다.
자, 이제 모두가 예제를 제공하기 때문에 나도 그렇게 할 것이라고 생각합니다.)
/*code is PL/SQL-styled pseudo-code because that's what's on my mind right now*/
g_some_global int := 0; --define a globally accessible variable somewhere.
function do_task_x(in_a in number) is
begin
b := calculate_magic(in_a);
if b mod 2 == 0 then
g_some_global := g_some_global + b;
end if;
return (b * 2.3);
end;
함수 do_task_x
갖는 일차 일부 계산의 결과를 반환하는 효과, 및 측면 가능한 글로벌 변수를 수정하는 효과.
물론, 이는 기본이고 부작용이 해석이있을 수 있고 실제 사용에 의존 수이다. 전역을 수정하기 위해이 함수를 호출하고 전역을 수정하는 것이 기본 효과 라고 말한 것보다 반환 된 값을 무시하면 됩니다.
답변
컴퓨터 과학에서, 함수 또는 표현은 어떤 상태를 수정하거나 호출 함수 또는 외부 세계와 관찰 가능한 상호 작용을 갖는 경우 부작용이 있다고합니다.
에서 위키 백과 – 부작용
수학적 의미에서 함수는 입력에서 출력으로의 매핑입니다. 함수 호출의 의도 된 효과는 입력을 리턴하는 출력에 맵핑하는 것입니다. 함수가 다른 작업을 수행하는 경우 문제가되지 않지만 입력에 출력을 매핑하지 않는 동작이 있으면 해당 동작이 부작용으로 알려져 있습니다.
보다 일반적인 용어로, 부작용은 구조물 설계자의 의도 된 효과가 아닌 임의의 효과이다.
효과는 배우에게 영향을 미치는 모든 것입니다. 여자 친구에게 이별 문자 메시지를 보내는 함수를 호출하면 많은 배우, 나, 그녀, 휴대 전화 회사의 네트워크 등에 영향을 미칩니다. 부작용이없는 함수를 호출하는 유일한 의도 된 효과는 함수입니다. 입력에서 매핑을 반환합니다. 그래서 :
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
이것이 함수로 의도 된 경우, 그것이해야 할 유일한 일은 void를 반환합니다. 부작용이없는 경우 실제로 문자 메시지를 보내지 않아야합니다.
대부분의 프로그래밍 언어에는 수학 함수를위한 구성이 없습니다. 그와 같은 구조는 사용되지 않습니다. 그렇기 때문에 대부분의 언어에는 방법이나 절차가 있다고 말합니다. 의도적으로 더 많은 효과를 낼 수 있도록 고안되었습니다. 일반적인 프로그래밍 용어에서, 아무도 메서드 나 프로 시저가 무엇인지 의도하지 않습니다. 누군가 누군가이 함수에 부작용이 있다고 말하면,이 구문은 수학 함수처럼 동작하지 않습니다. 그리고 누군가이 기능이 부작용이 없다고 말하면,이 구성은 수학 함수처럼 효과적으로 행동합니다.
순수한 기능은 정의에 따라 항상 부작용이 없습니다. 순수한 함수는 말할 수있는 방법입니다.이 함수는 더 많은 효과를 허용하는 구문을 사용하더라도 수학 함수와 동일한 효과 만 갖습니다.
부작용이없는 기능이 순수하지 않을 때는 누구에게나 알려주십시오. 순수 및 부작용이없는 용어를 사용하여 문장의 문맥에서 의도 된 주요 효과가 함수의 수학적 의도 된 효과가 아닌 경우, 그것들은 항상 동일합니다.
따라서 때로는 더 드물기는하지만 이것이 받아 들여진 대답에 사람들이 부족하고 오해하는 구별입니다 (가장 일반적인 가정이 아니기 때문에) 프로그래밍 기능의 의도 된 효과는 다음과 같습니다. 입력을 출력에 맵핑하기 위해 입력이 함수의 명시 적 매개 변수로 제한되지 않지만 출력이 명시 적 리턴 값으로 제한됩니다. 이것이 의도 된 효과라고 가정하면, 의도 한 효과의 다른 위치에서 입력을 허용했기 때문에 파일을 읽고 파일의 내용에 따라 다른 결과를 반환하는 함수는 여전히 부작용이 없습니다.
왜 이것이 중요한가?
그것은 통제와 유지에 관한 것입니다. 함수를 호출하고 다른 작업을 수행 한 다음 값을 반환하면 해당 동작을 추론하기가 어렵습니다. 실제 코드가 함수의 내부를 살펴보고 실제 코드가 수행중인 작업을 추측하고 정확성을 주장해야합니다. 이상적인 상황은 함수가 사용하는 입력이 무엇인지 알기 쉽고, 다른 작업을 수행하지 않고 출력을 반환한다는 것입니다. 이것을 조금 긴장을 풀고 사용중인 입력을 정확히 아는 것이 값을 반환하는 것을 알지 못하는 다른 일을하지 않는 것만 큼 도움이되지 않는다고 말하면 강제로 만족할 수 있습니다. 다른 작업을 수행하지 않고 입력을 가져 오는 위치에 관계없이 입력을 출력에 매핑합니다.
거의 모든 경우에있어서, 프로그램의 요점은 들어오는 것들에 매핑되는 것 이외의 다른 영향을 미치는 것입니다. 부작용을 제어하는 아이디어는 이해하기 쉽고 이해하기 쉬운 방식으로 코드를 구성 할 수 있다는 것입니다. 모든 부작용을 매우 명확하고 중심적인 장소에 모아두면 더 이상 일어나지 않는 곳이 어디인지보고 신뢰할 수 있습니다. 입력이 너무 명시 적이라면 다른 입력에 대한 동작을 테스트하는 데 도움이되며 사용하기 쉽습니다. 많은 다른 장소에서 입력을 변경할 필요가 없기 때문에 일부는 명확하지 않을 수 있습니다. 원하는 것을 얻을 수 있습니다.
프로그램의 행동을 이해하고, 추론하고 통제하는 데 가장 도움이되는 것은 모든 입력을 명확하게 그룹화하고 명시 적으로 분류하는 것뿐만 아니라 모든 부작용을 함께 그룹화하고 명시 적으로 표현하는 것이기 때문에, 일반적으로 사람들이 말할 때 부작용, 순수한 등
가장 도움이되는 것은 부작용의 그룹화와 그들의 명백 함입니다. 때로는 사람들은 그 의미를 의미하고 순수한 것이 아니라 여전히 “부작용”이라고 말함으로써 구별 할 것입니다. 그러나 부작용은 “의도 된 1 차 효과”와 관련이 있으므로 문맥 상 용어입니다. 놀랍게도이 스레드에서 많은 이야기를하지만, 내가 찾은 것은 덜 자주 사용됩니다.
마지막으로, dem 등원 (Idempotent)은 동일한 입력으로이 기능을 여러 번 호출하는 것을 의미합니다 (어느 곳에서 왔든 상관없이) 항상 동일한 효과 (부작용 여부)를 초래합니다.
답변
프로그래밍에서 부작용은 프로 시저가 범위 밖에서 변수를 변경하는 경우입니다. 부작용은 언어에 의존하지 않습니다. 부작용 (순수한 기능성 언어)을 제거하려는 일부 언어 클래스가 있지만 부작용이 필요한 언어가 있는지 확실하지 않지만 잘못되었을 수 있습니다.
내가 아는 한 내부 및 외부 부작용은 없습니다.
답변
다음은 간단한 예입니다.
int _totalWrites;
void Write(string message)
{
// Invoking this function has the side effect of
// incrementing the value of _totalWrites.
_totalWrites++;
Debug.Write(message);
}
부작용의 정의는 프로그래밍에만 국한된 것이 아니므로 단순히 약물의 부작용이나 음식을 너무 많이 섭취하는 것을 상상해보십시오.