Posts 선언형 프로그래밍(declarative programming)과 명령형 프로그래밍(imperative programming) 비교
Post
Cancel

선언형 프로그래밍(declarative programming)과 명령형 프로그래밍(imperative programming) 비교

TL; DR

  • 선언형 프로그래밍은 what 에 집중
  • 명령형 프로그래밍은 how 에 집중

간단한 예시를 통한 비교

길을 걷는 중에 누군가 “일산 이케아까지 어떻게 가야 하나요?” 라고 물었다고 해보자. 선언형과 명령형 프로그래밍이 대답한다면 다음과 같이 대답할 수 있을 것이다.

  • 선언형(what) : “경기 고양시 덕양구 권율대로 420 으로 가세요.”
  • 명령형(how) : “현재 위치에서 북쪽으로 500m 직진하세요. 그 다음 횡단보도를 건너세요.”
 선언형명령형
목표명시 O명시 X
알고리즘명시 X명시 O

선언형 프로그래밍(declarative programming)

선언형 프로그래밍은 크게 두 가지로 정의할 수 있다.

첫 번째 정의

어떻게(how)에 대한 부분은 추상화하고 무엇(what)과 같은지에 집중하는 프로그래밍을 선언형 프로그래밍이라 한다.

대표적인 언어로는 HTML, SQL, XML, Lisp, Haskell 등이 있다.

1
2
3
4
5
6
7
<!-- HTML -->
<article>
  <header>
    <h1>Hello, World!</h1>
    <img src="hello.jpg" />
  </header>
</article>

HTML 은 제목, 글꼴, 본문과 같이 ‘무엇’이 나타나야 하는지에 대한 묘사는 하지만, ‘어떤 방법’으로 컴퓨터 화면에 페이지를 표시 하는지는 묘사하지 않는다.

1
2
# SQL
SELECT * FROM CADETS WHERE ADDRESS='SEOUL';

SQL 도 마찬가지로 가져올 데이터가 ‘무엇’인지에 대해 작성하고, ‘어떻게’ 데이터를 검색해서 가져올 지는 묘사하지 않는다.

두 번째 정의

프로그램이 함수형, 논리형, 제한형 프로그래밍 언어로 쓰인 경우를 선언형 프로그래밍이라고 한다. 즉, 명령형 언어와 대비되는 언어를 통칭한다고 한다.

  • 함수형 프로그래밍 : 순수 함수를 조합하고 소프트웨어를 만드는 방식
  • 논리형 프로그래밍 : 논리 문장을 이용해서 프로그램을 표현하고, 계산을 수행하는 개념을 기반으로 두는 방식

명령형 프로그래밍 (Imperative programming)

명령형 프로그래밍은 선언형 프로그래밍과 반대되는 개념으로, 프로그램의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그래밍 패러다임이다. 즉, 컴퓨터가 수행할 명령들을 순서대로 써놓은 것을 의미한다.

대표적인 명령형 프로그래밍 언어로는 C, Java, Pascal 등이 있다.

JavaScript 를 통한 비교

배열을 매개변수로 받고, 각 요소들의 값에 2 를 더하는 함수를 각각의 프로그래밍 방식으로 표현하면 다음과 같다.

1
2
3
4
// 선언형 (declarative)
function add(arr) {
  return arr.map((item) => item + 2);
}
1
2
3
4
5
6
7
8
// 명령형 (imperative)
function add(arr) {
	const result = [];
	for (int i = 0; i < arr.length; i++) {
		result.push(arr[i] + 2);
	}
	return result;
}

여기서 map 함수도 내부적으로 명령형으로 작성되어 있을텐데, 이를 선언형이라고 하는 것이 과연 맞는 것일까?

위키백과에 따르면 다음과 같은 설명이 있다.

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

이를 기반으로 위의 질문에 대답하자면, 명령형 방식에서 for 문의 내부 변수가 for 문 외부로 노출되지 않도록 map 이라는 함수로 캡슐화 시켰기 때문에 선언형이라고 할 수 있다.

결국, 선언형 프로그래밍은 각각의 함수를 목적에 맞게 세분화하고, 최소한의 역할만 수행하도록 구현하여 함수의 조합으로 프로그램을 설계하는 것으로 해석할 수 있다. 이를 통해 함수의 유지보수가 쉬워지고, 재사용하기 쉬워지는 장점이 있다.

참고자료

This post is licensed under CC BY 4.0 by the author.

[nginx] rate limit 설정으로 인한 503 Service Unavailable 오류 해결 과정

[Spring] 의존성 주입(DI)과 제어의 역전(IoC) 개념 정리