CS

함수형 프로그래밍

뽀글보리 2021. 8. 27. 14:04
반응형

함수형 프로그래밍의 등장

  • 명령형 프로그래밍일경우 복잡하게 엉켜있는 스파게티 코드를 유지보수하는 것이 매우 어렵다.
  • 함수형 프로그램에서는 모든 것을 순수 함수로 나누어 문제를 해결한다.
  • 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 한다.

작은 문제도 함수로 나누어 문제를 해결한다.

// 1 ~ 10까지의 값이 i에 할당된다 
for(int i = 1 ; i < 10; i++)
{ System.out.println(i); }
process(10, print(num));
  • 무엇을 할 것인지에 포커스를 두는 프로그래밍
  • 따라서 출력하는 함수를 파라미터로 넘길 수 있다.

1급 함수

  • 함수가 1급객체로써의 의미를 가진다는 것은 포함관계를 갖는 데 있어서 최상위 레벨이 된다는 것이다.
  • 이에 따라 변수/함수/클래스 등이 함수의 구성요소가 될 수 있다.
  • 함수를 변수에 할당할 수 있다.
  • 함수를 매개변수로 전달할 수 있다.
  • 함수를 반환할 수 있다.
  • ex) javascript

함수형 프로그래밍의 컨셉

  1. 변경 가능한 상태를 불변상태로 만들어 side effect를 없애자
  2. 모든 것은 객체이다
  3. 코드를 간결하게 하고 가독성을 높여 구현할 로직에 집중시키자
  4. 동시성 작업을 쉽게 안전하게 구현하자

핵심 개념

  1. 순수 함수
    • 같은 입력 값이라면 항상 같은 결과 값을 반환한다.
    • OOP에서 오브젝트는 메소드를 수행하게 되는데 메소드의 수행결과는 멤버 변수의 상태에 따라서 결과가 달라진다.
    • 인풋 외에 다른 것에 의존하면 순수함수가 아니다.
    • //순수함수
      function greet(name){ 
          return "Hi ! " + name 
      }
      • //순수함수가 아니다
        stirng name = "byeori"
        
      function greet(){}
    • print("Hi!" + name)
  2. 고차 함수
    • 다른 함수를 인풋으로 받거나 함수를 아웃풋으로 반환할 수 있다.
    • 함수를 객체처럼 생각한다.
    • 함수 내 함수가 겹쳐지는 고차함수!
    • function makeAdjectifier(adjective){ 
          return function (string){ 
              return adjective + " " + string; 
             }; 
      } 
      var coolifier = makeAdjectifier("cool"); 
      coolifier("conference"); // => cool conference
  3. Do not iterate!
    • map, filter들을 사용한다.
    • java에서도 있어요
    • map(a -> print(a))
  4. 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"]`
  5. Persistent Data Structures
    • 그렇다면 배열을 변경할때 어떤식으로 동작하게 되는 걸까?
    • 만약에 100만개의 원소가 있는 배열의 값을 수시로 바꾸어 주어야 한다면, 다시 새로 객체를 반복해서 만드는 것이 매우 비효율적이라고 느껴질 수 있다.
    • 따라서 많은 함수형 프로그래밍 언어에서 Persistent Data Structures라는 자료구조를 사용하여 효율적으로 관리하게 된다.
    1. 해당 자료구조를 사용할 때 중간 n값을 변경한다고 했을 때 기존 포인터는 그대로 가져가고 n이 포함된 노드들만 새로 만드는 식으로 사용한다.
  6. 공유 상태를 피한다.
    • 공유 상태의 문제점 : 영향을 미치는 모든 공유 변수의 히스토리를 알아야 한다.
    • // 공유 상태에서는 함수 호출 순서에 따라 함수 호출의 결과가 변경됩니다. 
      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