Jun 개발노트

함수형프로그래밍

February 27, 2020

함수형 프로그래밍

  1. 정의 : 프로그래밍 패러다임이며, 함수로 모든걸 하는 프로래래밍, 제일 유행하는 프로래밍 방식

    • 예. 명령형프로그래밍(C), 객체지향프로그래밍(JAVA)
  2. 자바스크립트에서 왜 함수형 프로그래밍일까?

    • 자바스크립트로 객체지향을 구현할때 어려움(prototypees, this…)
    • 버그가 적고, 작성하기 쉽다, 유지보수에 용이
  3. 어떻게?

    • 함수형프로그래밍은 모든걸 함수로 표현한다(Input => Output)
    • 인풋과 아웃풋의 플로우를 생각해서 작성해야 한다.
    • Not Functional

      • 위에서 아래로 명령형 프로그래밍같이 작동한다. 단순히 콘솔에 보여주기만 한다. 아웃풋이 없다.
      • 인풋과 아웃풋을 표현하지 않음
      • var name = "Jun";
        var greeting = "Hi, I'm ";
        console.log(greeting + name);
        => "Hi, I'm Jun
    • Functional

      • 함수를 정의하고, 매개변수(Input), return(Output)을 정의한다.
      function greet(name){
          return  "Hi, I'm " + name;
      }
      
      greeting("Jun");
      => "Hi, I'm Jun
  4. Avoid side effects(use “pure” functions)

    • 최대한 순수하게 생각하자 => 인풋으로 계산해서 아웃풋을 만들어 반환하자
    • 오직 순수함수를 사용하여 부수효과를 줄이자
    • 주어진 인풋에서 아웃풋을 계산하여 반환하지 않는다
    • 전역변수로 아웃풋이 나온다면 순수함수가 아니다.(함수 외부의 것이 함수의 결과에 영향을 주는것이니까)

      // 순수함수가 아닌 이유 : 인풋이 없고, 아웃풋 또한 없으며 단순히 콘솔 창에 찍어주는것만 한다.
      var name = "Jun";
      function greet(){
          console.log("Hi, I'm " + name);
      }
      
      // 순수함수 : 아웃풋에 영향을 주는것 인풋 밖에 없다
      function greet(name){
          return  "Hi, I'm " + name;
      }
    • 오직 인풋만을 가지고 계산하여 아웃풋을 반환하여야 순수함수라고 할 수 있다.
  5. Use higher-order functions(1급 함수 => 인풋과 아웃풋을 함수로 사용할수있다. 함수로 받아서 함수로 반환 할 수 있다.)

    • 자바스크립트에서는 모든것이 객체이기 때문에 함수를 객체로 인풋과 아웃풋을 할 수 있다.
    • 함수내에 함수가 있는 구조로 만들수 있다.
    function makebeverage(fruit){
        return function(string){
            return fruit + string
        }
    }
    
    var apple = makebeverage('apple');
    apple('soda');
        => 'apple soda'
    • 다른 패러다임에서 없는것!!
  6. Don’t Iterate(for, while)

    • 반복문 대신 자바스크립트 내장함수인 map, reduce, filter를 사용하자
    • 고차함수 === map, reduce, filter
    const arr = [1,2,3,4,5];
    
    arr.map((value, index, arr)=>{
        // 배열에서 value, index를 하나씩 가지고 오며,
        // return 값에 원하는 결과값을 넣으면 해당 인덱스에 새로운 값을 넣어 새로운 배열을 리턴한다. 
    })
    
    arr.reduce((acc, value, index, arr) => {
        return acc + value
        // return의 결과값은 누산기(acc)에 할당되고 해당결과 누산값을 리턴
        // intial은 누산값의 초기값으로 만약이 없다면, 배열의 첫번째 요소를 사용한다.
    }, intial)
    
    arr.filter((value, index, arr) =>{
        // return 조건신이 참일때만 해당 벨류를 반환하여 새로운 배열을 리턴한다
    })
  7. Avoid mutability => use immutable data (변화하는 데이터보단 변화하지 않는 데이터를 사용하자)

    • 변화란 : 객체의 위치 변경, 안에 있는 데이터 변경 객체의 주소는 변하지 않지만, 객체 안에 있는 값들의 주소가 변경됨 우리는 객체의 주소를 가지고 핸들링 하기 때문에 변화를 캐치하기 힘들다.
    • 의도치 않은 변화로 인해 문제가 발생할 수 있다(다른 곳에서 rooms를 사용하고 있는데 rooms의 값이 변경되면 의도지않은 결과 발생(에러))

      var rooms = ['h1','h2','h3'];
      rooms[2] = 'h4';
      rooms;
      => ['h1','h2','h4']
    • immutable data : 고정된 위치 객체
    • map함수를 이용해 변경된 새로운 데이터를 만든다 원래 데이트는 불변성을 지킨다.
       var rooms = ['h1','h2','h3'];
       var newRooms = rooms.map(rm => {
           if(rm === 'h3'){return 'h4'}
           else{return rm}
       })
    
       newRooms; => ['h1','h2','h4']
       rooms; =>  ['h1','h2','h3']
       ```
  8. Persistent data structures for efficient immutability => Mori, Immutable.js

    • 데이터가 많고 객체가 거대하다면 원래 데이터를 복사하고 수정하는데 비효율적이다.
    • 데이터를 트리로 만들고 변화하는 새로운 노드를 만들어 원래 노드와 연결해서 새로운 트리를 만든다
    • 장점 : 원래 데이터를 전체 복사할 필요없이 새로운 노드를 만들어 연결시키면 효율성 증대 영속자료구조
    var xs = [0, 1, 2];
    var ys = [3, 4, 5];

    기본 배열

    var zs = xs ++ ys

    합

    xs = [a, b, c, d, f, g, h];
    
    fun insert (x, E) = T (E, x, E)| insert (x, s as T (a, y, b)) =
        if x < y then T (insert (x, a), y, b)
        else if x > y then T (a, y, insert (x, b))
        else s

    트리

    var ys = insert ("e", xs)

    결과

나의 의견 : 불면데이터를 업데이는데 최고의 효율적인 자료구조이며, 나의 개인적인 의견으로는 가상돔도 같은 원리로 작동하는것 같다


Written by Junho You 배운것을 기록하자