반응형
함수형 프로그래밍의 등장
- 명령형 프로그래밍일경우 복잡하게 엉켜있는 스파게티 코드를 유지보수하는 것이 매우 어렵다.
- 함수형 프로그램에서는 모든 것을 순수 함수로 나누어 문제를 해결한다.
- 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 한다.
작은 문제도 함수로 나누어 문제를 해결한다.
// 1 ~ 10까지의 값이 i에 할당된다
for(int i = 1 ; i < 10; i++)
{ System.out.println(i); }
process(10, print(num));
- 무엇을 할 것인지에 포커스를 두는 프로그래밍
- 따라서 출력하는 함수를 파라미터로 넘길 수 있다.
1급 함수
- 함수가 1급객체로써의 의미를 가진다는 것은 포함관계를 갖는 데 있어서 최상위 레벨이 된다는 것이다.
- 이에 따라 변수/함수/클래스 등이 함수의 구성요소가 될 수 있다.
- 함수를 변수에 할당할 수 있다.
- 함수를 매개변수로 전달할 수 있다.
- 함수를 반환할 수 있다.
- ex) javascript
함수형 프로그래밍의 컨셉
- 변경 가능한 상태를 불변상태로 만들어 side effect를 없애자
- 모든 것은 객체이다
- 코드를 간결하게 하고 가독성을 높여 구현할 로직에 집중시키자
- 동시성 작업을 쉽게 안전하게 구현하자
핵심 개념
- 순수 함수
- 같은 입력 값이라면 항상 같은 결과 값을 반환한다.
- OOP에서 오브젝트는 메소드를 수행하게 되는데 메소드의 수행결과는 멤버 변수의 상태에 따라서 결과가 달라진다.
- 인풋 외에 다른 것에 의존하면 순수함수가 아니다.
-
//순수함수 function greet(name){ return "Hi ! " + name }
-
//순수함수가 아니다 stirng name = "byeori"
-
print("Hi!" + name)
- 고차 함수
- 다른 함수를 인풋으로 받거나 함수를 아웃풋으로 반환할 수 있다.
- 함수를 객체처럼 생각한다.
- 함수 내 함수가 겹쳐지는 고차함수!
-
function makeAdjectifier(adjective){ return function (string){ return adjective + " " + string; }; } var coolifier = makeAdjectifier("cool"); coolifier("conference"); // => cool conference
- Do not iterate!
- map, filter들을 사용한다.
- java에서도 있어요
map(a -> print(a))
- Avoid mutability
- 모든 것을 immutable하게 만든다.
- 따라서 다음과 같이 객체의 값을 변경해야 한다.
var list = [1,2,3,4] list[2] = 5 //불가능 var new_list = list[0:2] + 5 + list[3] //이렇게 해야됨! //또 다른 방법 var rooms = ["h1", "h2", "h3"] var newRooms = rooms.map(function (rm) { if (rm == "h3") { return "h4"; } else { return rm; } }); // newRooms => ["h1", "h2", "h4"]`
- Persistent Data Structures
- 그렇다면 배열을 변경할때 어떤식으로 동작하게 되는 걸까?
- 만약에 100만개의 원소가 있는 배열의 값을 수시로 바꾸어 주어야 한다면, 다시 새로 객체를 반복해서 만드는 것이 매우 비효율적이라고 느껴질 수 있다.
- 따라서 많은 함수형 프로그래밍 언어에서 Persistent Data Structures라는 자료구조를 사용하여 효율적으로 관리하게 된다.
- 해당 자료구조를 사용할 때 중간 n값을 변경한다고 했을 때 기존 포인터는 그대로 가져가고 n이 포함된 노드들만 새로 만드는 식으로 사용한다.
- 공유 상태를 피한다.
- 공유 상태의 문제점 : 영향을 미치는 모든 공유 변수의 히스토리를 알아야 한다.
-
// 공유 상태에서는 함수 호출 순서에 따라 함수 호출의 결과가 변경됩니다. const x = { val: 2 }; const x1 = () => x.val += 1; const x2 = () => x.val *= 2; x1(); x2(); console.log(x.val); // 6 // 다음과 같이 함수를 정의했을 때, x1 -> x2로 호출 순서를 두느냐, x2 -> x1로 호출 순서로 두느냐에 따라 x의 값이 변합니다. // 따라서 히스토리를 알아야지 변수 값을 유추할 수 있다는 점이 공유 상태에서 가지는 문제점 입니다.
-
const x = { val: 2 }; const x1 = x => Object.assign({}, x, { val: x.val + 1 }); const x2 = x => Object.assign({}, x, { val: x.val * 2 }); console.log(x1(x2(x)).val); // 5 const y = { val: 2 }; x2(y); x1(y); // 함수형 프로그래밍에서는 immutable하기 때문에 함수 호출을 한다고 y값이 변하지 않습니다. console.log(x1(x2(y)).val); // 따라서 다음과 같은 방식으로 사용해야 합니다.
- immutable한 값을 사용하기 때문에 여러 쓰레드에서 접근을 하더라도 상관이 없고, Lock과 같은 보호 장치가 필요 없다.
반응형
'CS' 카테고리의 다른 글
[Web] 세션과 쿠키란 무엇일까? (0) | 2021.10.04 |
---|---|
도커와 쿠버네티스 (0) | 2021.08.31 |
[Spring] ControllerAdvice가 어떻게 작동할까? (0) | 2021.08.22 |
[Spring] AOP란 무엇일까? (0) | 2021.08.21 |
[JAVA] 예외 처리 종류 (0) | 2021.08.16 |