부수효과란 무엇인가?
어떤 함수가 실행되는 외부 환경과 연결점이 생기는 것을 부수효과라고 합니다.
유식한 말로는 lexical Environment의 outer에 연결된 모든 environment 내의 변수를 가져다 쓰는 것을 말합니다.
코드로 살펴보겠습니다.
const a = 10;
function Test() {
return a + 1
}
Test 함수는 외부의 변수 a를 자신이 실행할 때 가져다 씁니다. 이런 일이 누적되면 프로그램의 유지보수가 어려울뿐더러 사이드이펙트도 왕왕 발생 할 수 있습니다.
부수효과가 없는 함수를 순수함수라고 합니다. 함수형 프로그래밍에서는 순수함수가 아주 귀한 대접을 받습니다.
primitive type이 아닐 때가 문제다.
앞서 작성한 Either를 이용하여 로직을 작성했다고 가정하겠습니다.
// checker 함수 작성
Either.check({name : "kim"})(...)(...)
.map((value) => {
value.name = "na";
return value;
}).map((value) => {
console.log("first name : ", value.name);
})
이런 경우일 때는 두번째 map 함자는 부수효과가 생깁니다. primitive 값이 아닌 reference가 전달되기 때문입니다. 제 생각에는 아래 코드와 차이가 전혀 없어보입니다.
const data = {name : "kim"};
const A = () => {
data.name = "na";
return data;
}
const B = () => {
console.log("first name : ", data.name);
}
각 함자의 input, output은 독립적이어야 하는데 이렇게 연결되어도 괜찮을까요? 몇 가지 해결책을 생각해 보았습니다.
- map 함자에 주어진 사상의 결과를 항상 깊은 복사를 한다.
- immutable.js 같은 불변성 라이브러리를 사용한다
정도일 것 같습니다. 소박한 reference 값이면 상관 없겠습니다만 DOM이나 클래스 같이 큰놈이 들어온다면 퍼포먼스에 좋은 영향을 줄 것 같지는 않습니다.
Array 범주를 다시한번 돌아보자
javascript array는 어떻게 되어 있나 돌아봐야 할 것 같습니다. array의 map 함자도 위와 같은 문제가 없을까요?
const arr = [{name: "kim"}];
arr.map((value) => {
value.name += " gil dong";
return value;
}).map((value) => ...);
array의 map 함자는 그냥 리턴값이 array기만 하면 그걸로 되는 모양입니다. 생각해보건데 정의대로 할수 없는 현실적인 이유가 있기에 조금의 유연함이 반영된 것이 아닐까 하는 생각이 듭니다. 나무가 너무 뻣뻣하면 바람에 부러지기 마련이지요. 아니면 제가 생각을 잘못 하고 있을 수도 있습니다.
(이 글은 제 과거 블로그 글을 다시 정리하여 쓴 글입니다. 지식이 일천하여 틀린곳이 있을 수 있습니다.)
'프로그래밍' 카테고리의 다른 글
#6 맺으며 (0) | 2022.04.10 |
---|---|
#5 state 모나드 (0) | 2022.04.10 |
#3 maybe 모나드와 either 모나드 (0) | 2022.04.08 |
#2 함수의 합성 (0) | 2022.04.07 |
#1 함수형 프로그래밍에서 모나드는 무엇인가? (0) | 2022.04.07 |