[TIL] 프론트엔드 Day 9

📚 공부한 내용

1. 선언형 프로그래밍

  • 명령형 프로그래밍
    데이터를 다룰 때 어떠한 과정을 거쳐서 결과를 도출하는지에 집중하는 방식.

  • 선언형 프로그래밍
    데이터의 처리나 순서보다 실행 후의 결과가 목적이 되는 방식.

  • 선언형과 명령형
    선언형의 대표적인 언어가 바로 HTML이다. 우리는 웹 페이지의 구성요소들이 어떠한 과정을 거쳐서 화면에 표시되는지 알지 못하지만 우리가 원하는 대로 화면을 구성할 수 있다.

  //명령형 프로그래밍 예시
  let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  let even = [];
  for(let i = 0; i < arr.length; i++) {
    if(arr[i] % 2 === 0) {
      even.push(arr[i]);
    }
  }

  //선언형 프로그래밍 예시
  let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  let even = arr.filter(a => a % 2 === 0);

위의 코드가 또다른 예시이다. 명령형 프로그래밍에서 우리는 어떻게 arr의 원소를 순회할지, 순회를 멈추는 조건이 무엇인지, 각 원소를 어떤 조건에 따라서 처리할지 모든 과정을 나열한다. 반면, 선언형 프로그래밍에서는 원하는 결과를 나타낼 뿐이다.

2. 지연 평가

지연 평가는 제너레이터를 이용하여 리스트를 다루는 기법 중 하나이다. 제너레이터는 앞서 배운 내용대로 미리 계산하지 않고 이터레이터의 next()의 호출이 있을 때 다음 값을 평가한다. 제너레이터를 이용해서 기존의 range()map(), filter() 함수를 지연 평가되는 L.range(), L.map(), L.filter() 함수를 선언했다. 이 함수를 go() 함수를 이용해서 순차적으로 실행할 때, 기존의 함수와 다른 순서로 동작한다.

go(range(12),
   map(a => a + 10),
   filter(a => a % 2 === 0),
   take(4)
  );

go(L.range(12),
   L.map(a => a + 10),
   L.filter(a => a % 2 === 0),
   take(4)
  );
// take() 함수는 이터러블을 입력받아 지정된 개수만큼의 원소를 반환하는 함수이다.

위의 그림은 go() 내부에 있는 함수가 실행되는 순서를 간단하게 시각화 한 것이다. 일반 함수에서는 위에서 아래순서(range - map - filter - take)로 한 함수의 모든 연산이 끝나고 난 뒤에 다음 함수로 넘어간다. 마지막의 take() 함수로 인해서 4개의 결과만을 필요로 하지만 12개의 데이터를 전부 평가한다. 반면 지연 평가가 적용된 함수의 경우 take() 함수부터 실행되며, 이터레이터의 next()가 호출될 때 위에 위치한 함수(take - filter - map - range)에 값을 요청한다. 요청이 최종적으로 range()까지 도달하면 가장 위에있는 range()에서 값을 평가한 뒤 다시 아래로 반환한다. 이 과정을 통해서 단 하나의 값이 전달되며, 이 일련의 과정이 take()가 요구하는 4개의 결과를 충족하면 끝난다. 이런 동작 방식은 그림에서도 알 수 있듯, 더 적은 연산으로 동일한 결과를 얻을 수 있으며, 리스트나 이터러블의 길이가 길 수록 더 많은 시간을 줄일 것이다.


📝 더 공부할 것

  • 지연 평가를 실제로 실무에서 이용하는 사례
  • 실제 프로젝트에서의 선언형 프로그래밍 패러다임

🤔 느낀점

함수형 프로그래밍이나 선언형 프로그래밍에 대해서 공부할 수록 실제 업무에서 응용하는 방식이 궁금해진다. 프론트엔드에서 많은 양의 데이터를 처리할 일이 있을지는 몰라도 확실히 습득하고 이용할 수 있으면 좋을 것 같다.


Reference

프로그래머스 프론트엔드 데브코스

좋은 웹페이지 즐겨찾기