본문 바로가기

개발개발

선언형 프로그래밍이란 무엇일까?

선언형 프로그래밍, 선언적 프로그래밍이 무엇일까? 요즘 특히 많이 들리는 용어인데, 정확하게 어떤 의미인지 몰라서 개념을 정확하게 정리해보고자 한다. 우선 사전에서는 어떻게 정의되고 있는지 알아보았다.

선언형, 선언적 두가지 용어가 혼용되고 있는것을 자주 볼 수 있는데, 두가지 모두 같은 뜻으로 원문으로는 declarative 이고 번역차이라고 판단된다. 위키백과에 따르면 두 가지 뜻으로 통용되고 있다고 한다.

  • 프로그램이 어떤 방법으로(How) 해야 하는지를 나타내기 보다 무엇과(What)과 같은지를 설명하는 경우에 "선언형" 이라고 한다
  • 프로그램이 함수형 프로그래밍 언어, 논리형 프로그래밍 언어, 제한형 프로그래밍 언어로 작성된 경우에 "선언형" 이라고 한다.

선언형 프로그래밍에 대해 검색을 하다보면 보통 첫번째 의미로 검색이 많이되는데 간혹 프로그래밍 패러다임 글에서도 선언형 프로그래밍이 언급되어서 혼란스러웠었는데, 두가지로 통용된다고하니 나의 혼란스러움 한가지가 해결되었다. 그럼 이제 첫번째 의미에서의 선언형 프로그래밍이 뭔지 알아보자.

선언형 프로그래밍의 여러가지 예시들이 있는데, 보통 "여기가 XX인데 OO까지 어떻게 가야할까요?" 를 프로그래밍 언어로 옮기는 경우를 예로 들어 다음 처럼 설명한다.

  • 명령형 방식 (HOW) : 주차장 북쪽 출구를 나와 왼쪽으로 가세요. 12번가 출구에 도착할 때까지 15번 북쪽 도로를 타세요. 이케아를 끼고 우회전하세요. 직진하여 첫 번째 신호등에서 우회전 하세요. 다음 신호등을 지나 좌회전을 하세요.
  • 선언형 방식 (WHAT) : 내 주소는 OO시 XX로99 입니다.

이렇듯 어떻게에 대한 부분은 추상화를 하고 무엇을에 집중하는것이 선언적 프로그래밍이라고 한다. 설명을 보면 뭔가 알것 같기도 한데 사실 코드적인 예시가 아니다보니 잘 와닿지 않더라. 그래서 코드적인 예시를 찾아보았다. 다음은 배열을 파라미터로 받고 각 요소들의 값에 2를 곱하는 함수에 대한 정의다.

// 명령형 방식 (HOW)
function double (arr) {
  let results = [];
  for (let i = 0; i < arr.length; i++) {
    results.push(arr[i] * 2)
  }
  return results;
}

// 선언형 방식 (WHAT)
function double (arr) {
  return arr.map((item) => item * 2)
}

"이거 그냥 map이란 기본 제공 함수 사용해서 코드 축약시킨건데 이게 왜 선언형 방식이지? map 도 결국 구현부분을 보면 HOW 방식 처럼 되있을것이 아닌가?" 라는 의문이 들었다. 그런데 위키백과 설명에보면 다음과 같은 구절이 있다.

명령형 프로그래밍 언어로 선언형으로 프로그램을 작성할 수도 있다. 라이브러리나 프레임워크 내부의 비선언형 부분을 캡슐화하여 이렇게 할 수 있다

즉, 명령형 방식에서 for문 내부의 변수가 외부로부터 노출되지 않도록 map이란 함수로 캡슐화 시켰기 때문에 선언형이 되었다고 해석이 가능해진다. 그럼 함수로 쪼개조 쪼개면 그게 선언형 프로그래밍일까?

선언형 프로그래밍을 하기위해 위에서 언급한대로 How 가 아닌 What에 집중하여 기존 명령형 프로그래밍과는 다르게 설계를(코딩을) 할 필요가 있다. 이 부분에 대해서는 이 글에서 정리가 잘되어 있으니 참고 해보는게 정독을 한번 해보는게 좋을것 같다. 해당 글은 함수형 프로그래밍에 대한 글이기는 하지만 함수형 프로그래밍은 선언형 프로그래밍 패러다임을 따르기 때문에, 같은 맥락에서 받아들여도 될듯하다.

해당 글에서 처럼 각각에 함수를 목적에 맞게 나누고 최소한의 역할만을 수행하도록 구현하여 함수의 조합으로 프로그래밍을 설계하게 되면 각 함수의 유지보수가 쉬워지고 재사용하기 쉬워지는데(map이나 reduce란 함수를 생각해보면) 이것이 선언형 프로그래밍이고 이루고자하는 목적이 아닐까 하는 생각이 든다.

'개발개발' 카테고리의 다른 글

@RequestMapping 의 비밀  (0) 2022.05.13
문자열 해싱  (0) 2020.08.30
타입 스크립트에서 배열과 튜플  (0) 2020.03.11
Redux Style Guide  (0) 2020.01.30
리셀렉트에 대한 이해  (0) 2019.08.21