Skip to content

Latest commit

 

History

History
94 lines (53 loc) · 8.78 KB

imperative-and-declarative-programming.md

File metadata and controls

94 lines (53 loc) · 8.78 KB

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

이 글은 Anthony Cyrille의 Imperative and Declarative Programming을 번역한 글입니다.


한동안 저를 팔로우해온 분들은 제가 얼마나 큰 ReactJS-lover인지 알고 있을 겁니다.

제가 React를 좋아하는 이유는 우수한 성능 (Virtual DOM 덕분에), all-in-one-file 컴포넌트식 프로그래밍 또는 아름다운 JSX 문법 때문이 아닙니다.

가장 큰 이유는 JS를 선언적으로 작성할 수 있기 때문입니다.

선언적 UI

이것이 React의 핵심 파워입니다. 페이지를 어떻게 렌더링할지가 아니라, 무엇이 페이지의 모습이 되어야 할지 작성하는 것입니다.

View = Render(Props)

이를 통해 UI가 어떻게 동작할지 명확하게 이해할 수 있습니다. 영어를 읽을 수만 있으면, 코드를 간단히 살펴보는 것으로 컴포넌트가 어떻게 동작할지 예상할 수 있습니다.

여기에는 몇 가지 장점이 있습니다:

  • 실제 렌더링 구현에 신경 쓸 필요가 없습니다. 이것이 브라우저, 모바일 앱, 데스크톱, 임베디드 시스템 및 비디오 게임(Battlefield UI에서 사용되었지만 비디오를 찾을 수 없음)에서 React 코드를 사용할 수 있는 이유입니다.
  • 코드가 더 예측 가능합니다
  • 프로그램의 복잡도를 대폭 줄입니다

이제, 선언적 코드의 차이점과 작성 방법으로 넘어갑시다.

차이점

C언어를 사용해봤나요? 나아가서, 약간의 어셈블리어를 해보았나요? 컴퓨터가 해야 할 모든 동작을 어떻게 작성했는지 생각해봅시다. 아마도, "이 숫자를 가져와서, 레지스터에 넣고, 5를 더한 다음, 다시 RAM에 넣는다", 이렇게 길게 이어졌을 것입니다.

이처럼 컴퓨터가 어떻게 동작할지 지시하는 프로그래밍 방식을 명령형 프로그래밍이라고 합니다.

코드를 작성하는 다른 방법이 있습니다. 이 방법은 목표를 달성하는 데 필요한 절차 대신, 달성하고자 하는 결과를 작성하는 방법입니다. 이를 선언형 프로그래밍이라고 합니다.

명령형 프로그래밍에서는, 어떻게 해야 할지를 기술합니다.
선언형 프로그래밍에서는, 무엇을 원하는지를 기술합니다.

JS 예제를 봅시다.

code.png

Imperative - 명령형 / Declarative - 선언형 / Even more declarative - 극도의 선언형, Point-free

이 더미 코드는 배열의 원소들 각각에 대해 짝수만 골라내서, 2를 곱한 다음, 모두 합산합니다.

  • 명령형: 코드를 읽으면 어떤 동작을 하는지 이해할 수 있습니다. 하지만, 의도가 명확하지 않습니다. 각 단계가 어떤 의미를 가지며, 어떻게 연관되어 있을까요? 알아내기 어렵습니다- 이보다 더 긴 코드 조각을 상상해보세요.
  • 선언형: 조금 더 이해하기 쉽습니다. 모든 숫자를 가져와서, 홀수를 걸러 낸 다음, 나머지를 두 배로 늘려서 모두 합산한다. 또한 더 간결하며 결과를 얻기 위한 단계들의 의미가 더 명확합니다.
  • Point-Free : 좋습니다. 투머치로 느껴지겠지만, 잠시만 저와 함께 따라와 주세요. 코드란, 기본적으로 영어입니다. 앞의 코드에서 "i % 2 === 0"은 "i"가 짝수인 경우에만 true를 반환한다고 추론해야 합니다. "i * 2"가 "i를 두 배로"를 의미한다고 추론해야 합니다. reduce 내의 "acc + next"는 이전에 계산된 합계에 현재 숫자를 더한다는 의미라는 것을 추론해야 합니다. 우리는 머릿속에서 코드가 아닌 단어의 관점에서 생각하기 때문에, 이러한 코드를 의미에 매핑하는 과정이 끊임없이 필요해집니다.
    Point-free는, 영어에 가깝기 때문에 코드를 생각으로 번역할 필요가 없습니다. "모든 수를 가져와서, 홀수를 걸러 내고, 두 배로 늘리고, 모두 합산합니다"라고 코드가 직접 말합니다. 6줄의 명령형 코드를 1줄까지 압축했습니다. 적은 코드는 적은 버그를 의미합니다, 그렇죠?

그리고 저는 이미 여러분의 마음의 소리가 들립니다:

하지만 선언형 프로그래밍은 여전히 ​​보이지 않는 곳에서 명령형 프로그래밍을 사용하므로, 순수한 선언적 코드를 작성하는 것은 불가능해!

틀린 말은 아닙니다. 컴퓨터는 선언적 코드를 이해하지 못하며, 자신이 해야 할 의무와 그 방법을 단계별로 알려줘야만 하는 기계입니다. 그러나 핵심은 순수한 선언적 코드를 작성하는 게 아닙니다. 명령적 코드를 구현 세부 사항만 나타내도록 제한된 영역 속에 밀어 넣는 것입니다.

React로 돌아가서 다시 생각해봅시다. 그 자체로는, 그저 UI 라이브러리로, JSX를 React elements를 생성하는 함수로 변환해 줄 뿐입니다. 그리고 컴포넌트들의 생명 주기를 관리합니다. 그게 전부입니다. 정말 마법 같은 일은 렌더러에서 일어납니다.

"이렇게 보일 것이다"라고 선언만 해두면, 실제로 그리는 것은 각 환경에 맞는 렌더러가 알아서 해 준다. 렌더링에 관한 선언과 구현이 분리되어 있기에 가능한 것. (본문에 없으나, 이해를 돕기 위해 추가)

이러한 유연성 덕분에 위에서 언급한 모든 환경에 React를 이식 할 수 있습니다. React를 사용하는 개발자는 컴포넌트와 관련 작업에만 집중할 수 있습니다.

더 나아가서

함수형 프로그래밍에 관해 이야기하지 않고 JS의 선언형 프로그래밍에 대해서는 말하기가 어렵습니다.

함수형 프로그래밍은 순수 함수를 합성하고, 부작용을 피하며, 불변 데이터를 사용하여 소프트웨어를 구축하는 프로그래밍 스타일입니다.

좋아요, 뭐가 많네요. 잘게 쪼개봅시다:

  • 수학 교과 과정을 기억하나요? 함수 합성은 함수의 결과를 다른 함수의 입력으로 사용하는 과정입니다. 일반적으로 y = g(f(x))로 표현됩니다.
  • 순수 함수는 두 가지 조건을 충족해야 합니다. 동일한 입력일 때 동일한 출력을 반환하고, 부작용이 없어야 합니다.
  • 부작용은 함수 외부의 상태에 작용하는 등, 외부에서 관측 가능한 효과를 일으키는 모든 동작을 의미합니다.
  • 불변 데이터는 한번 정의되면 더는 변경할 수 없는 데이터입니다.

예제에서 우리가 사용한 함수들은 isPair, double, sum이 있었습니다. 그들은 모두 함수형 프로그래밍의 모든 규칙을 충족합니다. 그들은 순수합니다. 이것이 가독성이 높고, 예측할 수 있고, 테스트가 가능한 이유입니다.

함수형 프로그래밍은 본질적으로 선언형 프로그래밍 스타일입니다. 둘은 서로에 대해 언급하지 않고는 제대로 설명하기 어렵습니다. 함수형 테크닉을 사용하지 않고도 선언형 프로그래밍을 할 수 있지만, 두 가지를 결합하면 훨씬 더 강력해집니다.

더 나아가고 싶다면, 읽을거리가 있습니다:

더더욱 나아가서 Reactive Programming을 알아보고 싶을 수도 있습니다. Reactive Programming은 여러분의 선언형 스택 위에 놓을 다른 개념입니다.

다양한 패러다임의 구별

선언형 프로그래밍은 명령형 프로그래밍에만 반대되는 개념입니다. 즉, 대부분의 경우 두 가지 모두 다른 프로그래밍 스타일과 결합 할 수 있습니다. "명령형 프로그래밍과 함수형 프로그래밍" 중 하나를 선택할 필요가 없습니다. "선언형 프로그래밍과 객체 지향 프로그래밍" 또한 마찬가지입니다. 이런 비교는 사과와 오렌지를 비교하는 것과 다를 게 없습니다. 선언형/명령형을 같은 박스 안에 넣고, 나머지는 다른 박스에 넣으세요.

마무리

이 글이 마음에 들었다면 언제든지 박수를 치고, 댓글을 남기고, 개선 사항을 제안해 주세요. 이 내용을 다루지 않고는 멀리 나아갈 수 없기 때문에, 제 글이 JS와 함께하는 여행에 도움이 되었으면 합니다.