[CS/Functional programming] 함수형 프로그래밍
✅함수형 프로그래밍은 side effect를 배제하며 조합성을 강조하는 프로그래밍 패더다임이다.
- side effect를 배제한다 =>
순수 함수
를 만든다. => 오류를 줄이고 안정성을 높인다.- 조합성을 강조한다 =>
모듈화
수준을 높인다. => 생산성을 높인다.- 함수형 프로그래밍에서는 중복을 제거하거나 어떤 대상을 추상화할 때 함수를 사용하면 된다. 추상화의 단위가 함수이다.
- 함수형 프로그래밍은 값을 만들어놓는게 아니라 함수를 통과하면서 값을 만들어 낸다.
1급 객체
Javascript의 함수는 일급객체이다.
1급 객체의 조건
- 무명의 리터럴로 표현이 가능하다.
- 변수나 자료 구조(객체, 배열 등)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 반환값으로 사용할 수 있다.
순수 함수
1. 순수 함수
- input이 같으면 항상 동일한 output을 만드는 함수이다.
- input외에 외부의 상태에 영향을 받지 않는다.
- 리턴값 외에는 외부와 소통하는 것이 없다.
- 평가 시점이 중요하지 않다.
- 프로젝트 작업에서 유지보수가 쉽다.
- output 계산에 전역변수를 사용하지 않는다.
Example 1
function greet(name){
return "Hi, I'm" + name;
}
greet("jack"); //"Hi, I'm jack"
Example 2
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
- 순수 함수에서 객체의 값을 변형해 나갈 때 원래 있던 값은 그대로 두고, 새로운 값을 복사해서 원하는 모양을 만든다.
2.순수 함수가 아닌 함수 -side effect를 일으키는 함수
Example 1
var name = "jack";
var greeting = "Hi, I'm";
console.log(greeting + name); //"Hi, I'm jack"
name
이나greeting
에 다른 값이 재할당되면 결과가 바뀔 수 있다.
Example 2
var c = 10;
function add(a,b){
return a + b + c;
}
console.log((add(10,2));
Example 3
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
- 외부 or 들어온 인자의 상태를 직접 바꾼다.
고차 함수
- 함수를 값으로 다룰 수 있는 개념
- 변수에 함수를 담을 수 있다.
- 다른 함수를 input으로 받거나 함수를 output으로 반환하는 함수이기에 이경우 함수를 일종의 객체로 취급하게 된다.
- 순수 함수를 조합해서 어떤 로직안에서 평가를 할 것인지를 정하면서 큰 로직을 만들어간다.
- 함수를 인자로 받아서 원하는 시점에 사용한다.
- 어떤 for문을 반복하면서 필요한 부분에서 받은 함수를 여러 번 실행하는 형태를 띄는 것이 함수형 프로그래밍이다.
고차 함수 예시(in JS 내장 함수)
- Array.prototype.sort()
- Array.prototype.forEach()
- Array.prototype.map()
- Array.prototype.filter()
- Array.prototype.reduce()
- Array.prototype.some()
- Array.prototype.every()
- Array.prototype.find()
Example 1
var f1 = function(a) { retrun a * a }
console.log(f1); //function(a) { retrun a * a }
Example 2
function f3(f) {
return f();
}
console.log( f3(function(){return 10;}) ); //10
Example 3
function add_maker(a) {
return function(b) { //여기서 이 함수는 closure이기도 함 a라는 값을 이 함수에서 참고하기에 closure로서 a라는 함수를 기억할 수 있음. 또한 a라는 값을 참조할 뿐 변경하지 않기 때문에 순수 함수임
return a + b;
}
}
var add = add_maker(10); // 함수가 할당됨
console.log(add(20));
Example 4
function makeAdjectifier(adjective) {
return function (string) {
return adjective + "" + string;
};
}
var coolifier = makeAdjectifier("cool");
coolifier("conference"); //"cool conference"
maekAdjectifier
이라는 함수에 "conference"
를 전달하면 "cool conference"
가 나옴.
Example 5
✅함수형 프로그래밍에 자주 쓰이는 형식!
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 됨
함수형 프로그래밍 작성시 주의 해야할 사항
1. 반복문을 피하자
for
,while
등의 반복하는 코드를 작성하기 보다map
,reduce
,filter
와 같은 고차 함수를 사용하자.
함수형 프로그래밍에서는 map
을 이용해서 재료 목록과 '다지기' 함수를 전달하면 그 output으로 다져진 재료들의 목록이 나온다. 이후 reduce
로 모든 재료 목록을 어떠한 방식(e.g. 샌드위치 제조)으로 결합할 수 있다. 또한 filter
를 사용해서 싫어하는 재료를 뺄수도 있다.
2. immutable 데이터를 사용하자.
mutable
var rooms = ["H1", "H2", "H3"];
rooms[2] = "H4";
rooms; //["H1", "H2", "H4"]
만약 이런식으로 다른 곳에서 참조하고 있는 변수가 원본 데이터를 변경 시킨다면 이로 인해 발생한 버그들을 해결하기 어렵다.
immutable
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
참고
Author And Source
이 문제에 관하여([CS/Functional programming] 함수형 프로그래밍), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dami/CSFunctional-programming-함수형-프로그래밍저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)