Daehyunii's Dev-blog

[데브코스] TIL-108 명령형, 선언형 프로그래밍 본문

✏️ 2022. TIL/October (데브코스)

[데브코스] TIL-108 명령형, 선언형 프로그래밍

Daehyunii 2022. 10. 31. 00:06

  오늘부터는 바닐라 자바스크립트 기본 역량 강화와 관련된 본격적인 주제가 시작되었고 더 디테일한 주제가 시작되기 전에 명령형 프로그래밍과 선언적인 프로그래밍 방식을 이해하는데 초점을 둔 강의였다. 두 가지 개념에 대해서 오늘은 정리를 해보고자 한다.


명령형 프로그래밍이란?

  위키피디아의 정의를 따라보면, 컴퓨터 과학에서 명령형 프로그래밍은 선언형 프로그래밍과 반대되는 개념으로, 프로그래밍의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그램 패러다임의 일종이다. 자연 언어에서의 명령법이 어떤 동작을 할 것인지를 명령으로 표현하듯이, 명령형 프로그램은 컴퓨터가 수행할 명령들을 순서대로 써 놓은 것이다.

 

https://ko.wikipedia.org/wiki/%EB%AA%85%EB%A0%B9%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

 

명령형 프로그래밍 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 과학에서 명령형 프로그래밍(命令型 프로그래밍, 영어: imperative programming)은 선언형 프로그래밍과 반대되는 개념으로, 프로그래밍의 상태와 상태를 변

ko.wikipedia.org

 

  사실 사전적인 정의는 이해하는데 조금 복잡할 수 있겠다. 그치만 그 중에서 가장 중요한 부분은 컴퓨터가 수행할 명령들을 순서대로 써 놓은 것이라는 것이다. 즉, 명령형 프로그래밍은 "어떻게 구현하는가?"를 자세하게 기술하는 것에 초점이 맞춰져 있다. 다음 코드를 살펴보자.

 

function double(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) { // 어떻게 가공할것인가를 하나 하나 전부 넣음
    result.push(arr[i] * 2);
  }
  return result;
}

  double 함수에서는 반복문을 돌면서 하나 하나 전부 명령을 하고 있다. 이것이 바로 명령형 프로그래밍이다. 이와 반대되는 선언형 프로그래밍 방식에 대해 알아보자.


선언형 프로그래밍이란?

프로그램이 어떤 방법으로 해야 하는지를 나타내기보다 무엇과 같은지를 설명하는 경우에 "선언형"이라고 한다.

https://ko.wikipedia.org/wiki/%EC%84%A0%EC%96%B8%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

 

선언형 프로그래밍 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 선언형 프로그래밍(宣言型 프로그래밍, 영어: declarative programming)은 두 가지 뜻으로 통용되고 있다. 한 정의에 따르면, 프로그램이 어떤 방법으로 해야 하는지를

ko.wikipedia.org

  명령형 프로그래밍과 다르게 "어떻게 구현하는가?"가 초점이 아니라 "무엇을 구현해야 하는가"에 초점이 맞춰져 있다. 다음 코드를 보자.

//선언형(어떻게 처리할지는 이미 약속된 규칙으로 이미 정해져있고, 무엇을 원하는지에 대한 묘사가 중요)
function double(arr) {
  return arr.map(item => item * 2); // map이 중요하다기 보다는 item => item * 2 가 중요
}

  Array.prototype.map 프로토타입 메서드를 통해 명령형 프로그래밍에서 작성한 코드보다 간결하게 코드를 만들었다. 즉, 반복문을 통해 무엇을 처리하고 무엇을 하여 결과를 만들겠다는 명령형 프로그래밍과 다르게 map 메서드를 통해 반복하여 새로운 배열을 반환하는것은 이미 약속된 규칙을 활용하고 무엇을 원하는지에 대한 묘사가 더 중요한 부분이 된다. 유지 보수 측면에서도 많은 차이가 발생한다. 위의 코드들을 숫자인 경우에만 돌아가게 유지보수 해야 한다면 어떻게 될까??


명령형 프로그래밍 유지보수
function double(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    if(typeof arr[i] === 'number'){
      result.push(arr[i] * 2);
    }
  }
  return result;
}

  if문의 조건식을 활용하여 유지보수를 하였다. 위와 같은 경우 코드를 간단하게 추가하면 되기 때문에 간단해 보일 수 있지만 많은 부분의 유지 보수가 필요한 경우 코드는 한 없이 늘어나고 가독성을 떨어트릴 수 있다. 즉, 명령형 프로그래밍은 무엇을 해야하는지 하나 하나 다 지정해야 한다. 그래서 코드가 복잡해지거나 많아지면 피곤해질 수 있다.


선언형 프로그래밍 유지보수
function double(arr) {
  return arr
      .filter(item => typeof item === 'number') //number인 요소만 뽑아서 배열로 반환
      .map(item => item * 2)

  명령형 프로그래밍과는 다르게 map 메서드를 실행하기에 앞서 filter 메서드를 통해서 조건을 추가하고 이를 다시 map 메서드로 반복하여 작동시킨 뒤 새로운 배열을 만들어서 반환하게 만들어 줄 수 있다. 명령형 프로그래밍에 비해 코드가 굉장히 깔끔하다는 것을 알 수 있다.

 

  위의 내용들을 토대로 비교해 보면 명령형 프로그래밍과 선언형 프로그래밍에 대해서 어떤 차이점이 있는지 명확하게 비교할 수 있다. 개념적으로는 비교하며 공부하기는 조금 까다로운 내용일 수 있지만 위의 코드들을 비교해보면 쉽게 비교가 가능하다. 그리고 명령형 프로그래밍에 비해 선언형 프로그래밍이 시각적으로 보아도 훨씬 깔끔한 코드 구성임을 알 수 있다. 


오늘을 마무리 하며

 

  명령형 프로그래밍과 선언형 프로그래밍의 차이점에 대해서 오늘은 어느 정도(?) 이해할 수 있었다. 그 동안에는 이런게 있다 정도의 느낌이었고 코드를 어떻게든 만들어 내는데 집중했었는데 이제는 선언형 프로그래밍 패러다임에 맞춰 코드를 작성하도록 노력해야 겠다는 생각이 들었다. 그러기 위해서는 고차함수들에 대한 이해도를 조금 더 높이고 이를 이용하고 활용하는 방법을 잘 익히는것이 중요할 것이라는 생각이 들었다. 결론,,고차함수 복습하자,,,