"이 버튼을 누르면, 팝업을 띄우고, 버튼 색을 파란색으로 바꾸고, 텍스트는 '완료'로 변경해 줘." 이런 기획 요구사항을 코드로 옮기다 보면, 우리는 자연스럽게 모든 단계를 하나하나 명령하게 됩니다. 하지만 기능이 복잡해질수록 이 '명령'들의 순서는 꼬여가고, 코드는 스파게티처럼 얽혀서 "내가 왜 이걸 이렇게 짰더라?" 하고 머리를 쥐어뜯게 되죠. 🍝
만약 우리가 컴퓨터에게 일일이 명령하는 대신, "이 버튼은 '완료' 상태일 때 파란색 배경과 '완료'라는 텍스트를 가져야 해" 라고 원하는 최종 상태만 알려준다면 어떨까요? 이 생각의 전환이 바로 버그를 줄이고 코드의 가독성을 극적으로 높이는 선언형(Declarative) 프로그래밍의 핵심입니다.

택시 기사님에게 길을 알려주는 두 가지 방법
명령형(Imperative) 과 선언형(Declarative) 프로그래밍의 차이를 이해하는 가장 좋은 방법은 택시를 타는 것에 비유하는 것입니다.
- 명령형 (Imperative) 👨🏫: "어떻게(How) 할지 알려주겠다!" "기사님, 여기서 출발해서 첫 번째 신호등에서 좌회전하고, 300미터 직진하다가 주유소 끼고 우회전해서, 터널 지나고 바로 나오는 육교 밑에서 세워주세요." → 목적지에 도달하기 위한 모든 과정과 절차를 하나하나 직접 지시합니다. 만약 중간에 길이 막히거나 공사 중이면, 우리는 새로운 경로를 다시 일일이 알려줘야 합니다.
- 선언형 (Declarative) 🎯: "무엇을(What) 원하는지 알려주겠다!" "기사님, 서울시청 앞으로 가주세요." → 우리는 최종 목적지(결과) 만 말합니다. 그곳까지 가는 가장 빠른 길을 찾고, 교통 체증을 피하고, 어떤 길로 갈지는 모두 기사님(컴퓨터, 프레임워크)의 전문성에 맡깁니다. 우리는 '어떻게' 갈지에 대해서는 신경 쓰지 않습니다.
대부분의 주니어 개발자들은 C언어나 Java의 절차 지향 스타일에 익숙하기 때문에 자연스럽게 명령형으로 코드를 작성합니다. 하지만 현대적인 프로그래밍 패러다임은 점점 더 선언형을 지향하고 있습니다.
코드로 보는 차이 (바닐라 JS vs. React)
웹페이지에서 버튼을 클릭하면, 버튼의 텍스트가 '로딩 중...'으로 바뀌고 비활성화되는 간단한 기능을 만든다고 상상해 봅시다.
👎 명령형 방식 (Vanilla JavaScript)
// HTML: <button id="action-btn">실행</button>
const actionButton = document.getElementById('action-btn');
actionButton.addEventListener('click', () => {
// 1. 버튼의 텍스트를 직접 찾아서 바꾼다. (How)
actionButton.innerText = '로딩 중...';
// 2. 버튼을 직접 찾아서 비활성화시킨다. (How)
actionButton.disabled = true;
// ... API 호출 로직 ...
});
우리는 document라는 거대한 객체에서 원하는 DOM 요소를 직접 찾아와, 그 속성을 어떻게 바꿀지 하나하나 명령하고 있습니다.
👍 선언형 방식 (React.js)
// React Component
function ActionComponent() {
const [isLoading, setIsLoading] = useState(false);
const handleClick = () => {
setIsLoading(true);
// ... API 호출 로직 ...
};
// 우리는 그저 "isLoading 상태가 true이면, 버튼은 이런 모습이어야 한다"
// 라고 최종 상태(What)를 선언할 뿐이다.
return (
<button onClick={handleClick} disabled={isLoading}>
{isLoading ? '로딩 중...' : '실행'}
</button>
);
}
React 코드 어디에도 "버튼의 텍스트를 이걸로 바꿔라" 또는 "버튼을 비활성화해라" 라는 직접적인 명령은 없습니다. 우리는 단지 isLoading이라는 상태(state) 가 true일 때와 false일 때, 버튼이 어떤 모습이어야 하는지를 정의(선언)했을 뿐입니다. 상태를 바꾸면, 나머지 복잡한 과정은 React가 알아서 처리해 줍니다.
선언형 패러다임은 어디에나 있다
이 강력한 개념은 UI 개발에만 국한되지 않습니다.
- SQL: SELECT name FROM users WHERE country = 'Korea' 라는 쿼리는 "한국에 사는 유저의 이름을 '가져오는 방법'"을 지시하지 않습니다. 그저 "한국에 사는 유저의 이름이라는 '데이터'"를 달라고 선언할 뿐입니다.
- HTML/CSS: <h1>Hello</h1>는 브라우저에게 "큰 글씨를 그리는 방법"을 알려주지 않습니다. "여기에 큰 제목이 있다"는 구조를 선언합니다. color: red; 역시 "픽셀을 빨갛게 칠하는 방법"이 아닌, "색깔이 빨갛다"는 상태를 선언하는 것입니다.
- 인프라 관리 (Terraform): "서버 3대를 만들고, 로드밸런서를 연결하고, 보안 그룹을 설정하는 방법"을 스크립트로 짜는 대신, "우리가 원하는 인프라의 최종 구성은 서버 3대와 로드밸런서 1개이다" 라고 코드로 선언합니다.
마치며
선언형 프로그래밍은 개발자가 "어떻게?"라는 지루하고 오류가 발생하기 쉬운 절차에서 벗어나, "무엇을?"이라는 문제의 본질에 더 집중하게 해주는 강력한 사고방식입니다. 🧠
애플리케이션의 복잡성을 상태(State)라는 하나의 변수로 단순화하고, 그 상태가 변함에 따라 시스템이 어떤 모습이어야 하는지만을 기술하는 것. 이것이 바로 거대하고 복잡한 소프트웨어를 우아하게 관리하는 현대 개발의 핵심 비결 중 하나입니다. 여러분의 다음 코드에는 '명령' 대신 '선언'을 담아보는 건 어떨까요?