✅함수형 프로그래밍은 side effect를 배제하며 조합성을 강조하는 프로그래밍 패더다임이다.
- side effect를 배제한다 =>
순수 함수
를 만든다. => 오류를 줄이고 안정성을 높인다.- 조합성을 강조한다 =>
모듈화
수준을 높인다. => 생산성을 높인다.- 함수형 프로그래밍에서는 중복을 제거하거나 어떤 대상을 추상화할 때 함수를 사용하면 된다. 추상화의 단위가 함수이다.
- 함수형 프로그래밍은 값을 만들어놓는게 아니라 함수를 통과하면서 값을 만들어 낸다.
Javascript의 함수는 일급객체이다.
- 무명의 리터럴로 표현이 가능하다.
- 변수나 자료 구조(객체, 배열 등)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 반환값으로 사용할 수 있다.
function greet(name){
return "Hi, I'm" + name;
}
greet("jack"); //"Hi, I'm jack"
var obj = { val : 10};
function add(obj, b) {
return { val: obj.val + b }
}
console.log(obj.val); //10
add(obj, 20);
console.log(obj.val); //10
var name = "jack";
var greeting = "Hi, I'm";
console.log(greeting + name); //"Hi, I'm jack"
name
이나 greeting
에 다른 값이 재할당되면 결과가 바뀔 수 있다.var c = 10;
function add(a,b){
return a + b + c;
}
console.log((add(10,2));
var c = 20;
function add(a,b) {
c = b;
return a + b;
}
console.log(c); //20
console.log(add(20,30)); //50
console.log(c); //30
var f1 = function(a) { retrun a * a }
console.log(f1); //function(a) { retrun a * a }
function f3(f) {
return f();
}
console.log( f3(function(){return 10;}) ); //10
function add_maker(a) {
return function(b) { //여기서 이 함수는 closure이기도 함 a라는 값을 이 함수에서 참고하기에 closure로서 a라는 함수를 기억할 수 있음. 또한 a라는 값을 참조할 뿐 변경하지 않기 때문에 순수 함수임
return a + b;
}
}
var add = add_maker(10); // 함수가 할당됨
console.log(add(20));
function makeAdjectifier(adjective) {
return function (string) {
return adjective + "" + string;
};
}
var coolifier = makeAdjectifier("cool");
coolifier("conference"); //"cool conference"
maekAdjectifier
이라는 함수에 "conference"
를 전달하면 "cool conference"
가 나옴.
✅함수형 프로그래밍에 자주 쓰이는 형식!
function f4(f1, f2, f3) {
return f3(f1() + f2());
}
f4(
function() {return 2;},
function() {return 1;},
function(a) {return a * a;}
);
// 3*3한 결과인 9가 return 됨
for
,while
등의 반복하는 코드를 작성하기 보다map
,reduce
,filter
와 같은 고차 함수를 사용하자.
함수형 프로그래밍에서는 map
을 이용해서 재료 목록과 '다지기' 함수를 전달하면 그 output으로 다져진 재료들의 목록이 나온다. 이후 reduce
로 모든 재료 목록을 어떠한 방식(e.g. 샌드위치 제조)으로 결합할 수 있다. 또한 filter
를 사용해서 싫어하는 재료를 뺄수도 있다.
var rooms = ["H1", "H2", "H3"];
rooms[2] = "H4";
rooms; //["H1", "H2", "H4"]
만약 이런식으로 다른 곳에서 참조하고 있는 변수가 원본 데이터를 변경 시킨다면 이로 인해 발생한 버그들을 해결하기 어렵다.
var rooms = ["H1", "H2", "H3"];
var newRooms = rooms.map(function (rm) {
if (rm === "H3") { return "H4"; }
else {return rm;}
});
newRooms;//["H1", "H2", "H4"]
rooms; //["H1", "H2", "H3"]
예를 들어 위와 같이 배열 같은 데이터를 사용한다 했을 때 immutable 데이터의 문제는 immutable을 유지하기 위해 계속 사본을 생성해야 한다는 점이다. 만약 1개의 room 정보를 바꾸려면 배열 전체를 새로 만들어야 한다. 1개의 요소만 바꾸면 되는데 바꾸지 않아도 되는 요소를 포함해서 바꿔야 되기에 시간이 오래 걸리게 되고, 그 결과 객체가 크고 복잡할 수록 효율이 떨어질 수 밖에 없다.
- 이 문제를 구조를 공유하는 방식으로 해결할 수 있다. (e.g. Linked List..)
immutable data
생성 라이브러리에는Mori
와Immutable.js
가 있다.
https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming
참고