thread-safe
하다.1급 객체(first class citizen)
함수형 프로그래밍을 적용시켜보며 가장 고민했던 부분이 순수 함수이다.
순수 함수는 어떤 함수에 동일한 인자를 주었을 때 항상 같은 값을 리턴하는 함수이다. 또한 외부의 상태(변수)를 변경하지 않는 함수를 뜻한다.
순수 함수로 구현하는 과정에서 어떤 기준으로 함수를 분할해야 하는지 기준이 세워지지 않았다. 단지, 지금 당장 구현하는 기능에 맞춰서 순수 함수로만 구현하겠다는 욕심에 쓸데없는 기능들로만 이루어진 함수를 구현해야 한다면 객체지향적인 방식이 가독성과 재사용성이 더 좋지 않을까라는 고민을 했다...
기능이 복잡해질 수록 서로 참조가 없는 순수 함수로 구현하기 위해 엄청난 양의 함수가 구현되는 경우도 있지 않을까?
많은 사람들이 의문점을 갖는 부분이다...내가 직접 함수형 프로그래밍을 구현해보면서 잡았던 기준으로는 X
였다.
순수 함수는 참조투명성을 가져야 한다. 때문에 함수 외부의 영향을 받지 않는 것을 의미한다.
만약, 순수 함수 A를 순수 함수 B에서 호출한다고 가정하자.
순수 함수 A의 내부 기능이 새롭게 바뀌고 반환값도 변경되었지만 여전히 순수 함수의 형태를 띄고 있더라도 순수 함수 B의 값은 기존과 다른 결과값을 반환할 것이다.
결국 함수 B는 외부 함수인 A의 영향을 받아 일정한 값을 도출하지 못할 것이라고 생각했다.
순수 함수의 동일한 인자를 주었을 때 항상 같은 값을 리턴한다는 조건을 조금 다르게 해석한 부분이 있지만, 조건의 의도 측면에서 사용하지 않는 쪽이 가깝다고 생각했다.
함수형 프로그래밍을 학습해보며 느낀 개인적인 의견이다.
[2021-07-29]
나는 순수 함수끼리 참조를 할 때 하나의 순수 함수가 변한다면?
변한 이후에도 순수 함수의 형태를 유지하고 있다면?
이라는 가정이 있었다.
하지만 동료들과 토론을 해보니 이 가정 자체가 잘못된 것이 아닐까 라는 의견들이 나왔다. 나의 가정을 온전히 따라가다보면 함수 모듈화를 상당히 많이 해야할테고 함수형 프로그래밍의 의도와 달라지지 않을까 생각하게 되었다. 결국 위에 작성한 의문점... 부분으로 다시 돌아가 고민하게 되지 않을까.
나의 가정의 실수는 수학적으로 f(g(e))라는 것이 함수가 변할 수 있다는 것을 가정하지 않는다고 한다.
새롭게 가정한 기준을 둔다면 순수함수 내에서 순수함수를 사용할 수 있다.라는 의견을 생각하게 되었다.
확실한 정답은 알 수 없지만 의견 공유의 과정 자체가 나의 생각의 폭을 유연하게 늘릴 수 있었다.
선언할 당시의 환경을 기억했다가 나중에 호출될시 원래의 환경에 따라 호출되는 함수
클로저의 사전적인 의미는포섭
이다.
function closure(dataA) {
return function(dataB) {
return dataA + dataB
}
}
const cl = closure(5);
cl(10); // 15 return
cl
변수에 데이터 5
와 함께 클로저 함수를 선언했다.5
를 매개변수로 넘겨받은 것을 말하며 5
를 포섭
했다.cl
변수를 호출할 때 10
을 넘겨줬다.포섭
한 데이터 5
와 호출시에 넘긴 10
을 사용하여 결과값을 반환한다.렉시컬 환경
을 포섭
하여, 실행될 때 함께 이용된다.자유변수
라고 한다.private
효과를 가져온다.여러 개의 인자를 가진 함수를 호출 할 경우, 파라미터의 수보다 적은 수의 파라미터를 인자로 받으면 누락된 파라미터를 인자로 받는 기법을 말한다.
function closure(dataA) {
return function(dataB) {
return dataA + dataB
}
}
closure(5);
/* return 값
ƒ (dataB) {
return dataA + dataB
}
*/
closure(5)(10); // return 15
클로저
를 먼저 이해한 후 커링
을 봤을 때, 변수에 담는 과정을 없앴을 때의 결과라고 생각했다.cl
을 호출하면 같은 결과가 나왔다.// 전역 범위 (global scope)
var e = 10;
function sum(a){
return function sum2(b){
return function sum3(c){
// 외부 함수 범위 (outer functions scope)
return function sum4(d){
// 지역 범위 (local scope)
return a + b + c + d + e;
}
}
}
}
var s = sum(1);
var s1 = s(2);
var s2 = s1(3);
var s3 = s2(4);
console.log(s3) //log 20