[프로그래밍 언어론] 명령형(Imperative)프로그래밍과 선언형(Declarative)프로그래밍

명령형(Imperative) 프로그래밍

명령형 프로그래밍이란 프로그램의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그래밍 패러다임의 일종이다. 쉽게 설명하자면, 컴퓨터가 수행할 명령들을 순서대로 써 놓은 것이라고 볼 수 있다.

 

이러한 명령형 프로그래밍은 "how to solve it", 즉 어떻게 그것을 해결할 것인가에 관심이 있다. 

 

거의 대부분의 컴퓨터 하드웨어는 명령형으로 구현된다. 거의 모든 컴퓨터 하드웨어들은 기계어를 실행하도록 설계되어 있는데, 보통 이것이 명령형으로 써져 있다. 

 

포트란, ALGOL, C언어 등이 명령형 프로그래밍 언어의 일종이다.

 

 

선언형(Declarative) 프로그래밍

선언형 프로그래밍은 보통 두 가지 뜻으로 통용된다.

 

첫 번째는 프로그램이 무엇을 해야 할지를 나타내는 경우를 선언형이라고 한다. 예를 들어 컴퓨터 화면에 웹 페이지를 나타낼 때 "어떤 방법"으로 페이지를 나타내야 하는지 보다 제목, 본문, 그림 등과 같이 "무엇"을 화면에 나타내야 할지를 고민하는 것이 선언형 프로그래밍이다.

 

두 번째는 프로그램이 함수형, 논리형, 제한형 프로그래밍 언어 등으로 작성된 경우에 선언형이라고 한다. 

(참고 : https://ko.wikipedia.org/wiki/선언형 프로그래밍 )

 

SQL, HTML 등이 선언형 프로그래밍 언어의 일종이라고 할 수 있다. (HTML은 언어가 아니다!라는 사람도 있음)

 

아주 간단한 예시를 들어보자.

 

SELECT * FROM Users WHERE Country='서울';

 

위와 같은 SQL 쿼리는 Users 테이블에서 서울에 거주하는 사람들의 정보를 가져온다. 이때 정보를 어떻게(How) 가져오는 것보다 어떤 정보(What)를 가져올지에 대해 더 관심이 많다. 서울에 거주하는 사용자들의 정보를 가져오는 방법에 대한 구현은 추상화되어 있다.

 

 

명령형 vs 선언형 프로그래밍

명령형 vs 선언형
[그림 1] 명령형 vs 선언형

 

명령형 프로그래밍은 무엇을 어떻게(How) 할 것인가에 가깝고, 선언형 프로그래밍은 무엇을(What) 할 것인가에 가깝다. 

 

현실을 예로 들어 설명해보자.

 

 

첫번째 예시

 

당신은 애인과 함께 근사한 레스토랑에 가서 식사를 하기로 결정했다. 즐거운 기분으로 레스토랑에 도착한 뒤 안내 데스크에 다가가 이렇게 말한다. 

 

  • 명령형 방식 : "저기 창가 쪽 자리가 비었네요. 저 자리로 걸어가서 앉을게요"
  • 선언형 방식 : "두 명 앉을 자리 부탁해요"

 

명령형은 내가 자리를 어떻게 앉을 것이지에 대해서, 선언형은 어떤 것을 원하는지를 말했다.

 

 

두 번째 예시

 

낯선 사람이 당신에게 OO호텔이 어디 있는지를 묻는다. 당신은 그곳이 어디 있는지 잘 안다. 이때 당신은 이렇게 말한다.

 

  • 명령형 방식 : "여기서 쭉 직진하시다가 롯데리아가 보이시면 우회전 하세요. 직진하다가 두 번째 신호등에서 좌회전하세요. OO호텔이 보일 겁니다"
  • 선언형 방식 : "OO 호텔은 xxx동 xxx로 xx길 10에 있습니다.

 

명령형은 OO호텔에 어떻게 가는지에 대해서, 선언형은 어떤 곳을 가야하는 지를 말했다.

 


 

많은 선언형 접근 방식은 명령형으로 구현된 것들이 추상화되어 있어야 한다.

 

위의 예시에서 선언형 방식을 보면 "자리는 어떻게 앉지?", "주소만 알고 어떻게 찾아가지?"와 같은 의문이 들 수 있다.

사실 이것은 다음과 같은 가정이 숨겨져 있다.

 

1. 첫 번째 예시 : 직원이 고객들을 자리로 안내할 방법을 알고 있다.

 

2. 두 번째 예시 :  낯선 사람이 내비게이션을 가지고 있다.

 

이러한 가정 덕분에 고객은 자리를 찾아가는 방법이 아닌 자리 그 자체를 요청하고, 낯선 사람에게 길을 찾아가는 방법이 아닌 주소만을 알려줘도 됐던 것이다.

 

이처럼 많은 선언형 접근 방식은 명령형으로 구현된 것들이 추상화되어 있어야 한다.

 

 

다음과 같은 JavaScript 코드를 살펴보자.

 

// 배열을 파라미터로 받고 각 요소들의 값에 2를 곱하는 함수

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

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

 

두 함수는 배열을 파라미터로 받아 각 요소들의 값에 2를 곱하는 같은 기능을 한다. 명령형 방식을 보면 어떻게 배열의 요소들에 2를 곱할지 설명하는 식으로 작성됐다. 하지만 선연형 방식은 어떻게 보다 무엇을 할지만 작성됐다.

 

즉, JavaScript에 내장된 map을 이용해 같은 기능을 수행했다. 개발자는 map의 내부가 어떻게 되어있는지 모르지만, 그것을 신경 쓸 필요가 없다. 

 

이러한 방식은 가독성을 높이고, 상태를 변경하는 모든 지점들이 map안으로 추상화되어 직접 상태를 변경하지 않아도 된다. 

 

선언형 프로그래밍에 속하는 대표적인 프로그래밍 방식이 함수형 프로그래밍이다. 

 


참고

 

1. https://ui.dev/imperative-vs-declarative-programming

2.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

3. https://boxfoxs.tistory.com/430

 

반응형

댓글

Designed by JB FACTORY