주문서와 레시피
선언형 프로그래밍, 명령형 프로그래밍. 이런 단어 들어보신 적 있으실까요? 네, 개발자가 아니라면 아마 없으시겠죠… (쭈굴)
하지만 프로그래밍을 잘 모르는 분이라도 ‘프론트엔드’나 ‘리액트’라는 말을 들어보셨을 겁니다?!
쉽게 말해 프론트엔드는 UI를 그리는 개발자예요. ‘리액트’는 UI를 그리는 기술 중 하나이고요.
UI 기술은 수많은 것들이 나오고 인기를 얻고 사라지지만, 리액트는 그 중에서도 지난 10년 동안 부동의 탑을 유지하고 있습니다. 가장 유명하고 인기 있는 기술이죠.
SNS가 UI 기술이라면, 리액트는 인스타그램 정도라고 생각하시면 되겠습니다.
이 리액트가 왜 이렇게 대세가 되었냐? 그 이유 중 하나가 리액트가 ‘선언형 프로그래밍’을 기본으로 삼았기 때문이었어요. 2010년대 초반만해도, UI 기술은 대부분 명령형이 대세였거든요. 근데 리액트가 확 뜨면서, 지금은 웹, 모바일을 막론하고 선언형이 대세가 되었습니다.
마치 인스타그램이 사각형 사진에 필터를 유행시켰듯이, 리액트는 UI 개발에서 선언형을 대세로 만들었습니다.
그렇다보니 개발자들은 ‘선언형 프로그래밍’에 대해서 필수적으로 배우고 알고 있어요. 어떤 코드를 보여주면 흠 이건 선언형이네. 흠 이건 절차형이네. 이런 걸 한눈에 알아봅니다. 이 라이브러리는 UI ‘애니메이션을 선언형으로 작성할 수 있게 해주는 라이브러리야’, 같은 말을 달고 살고요.
그래서! ‘선언형’이 무엇이냐 설명을 해보도록 하겠습니다. 개발자가 아닌 분들도 쉽게 이해할 수 있도록요. (그냥 처음부터 선언형이 뭐다라고 하면 노관심일 것 같아 앞에 어그로 길게 끌었습니다…)
알바와 일하는 2가지 방법자, 여러분이 식당 사장이라고 해봅시다. 맛있는 브런치 식당을 열었습니다. 개업 후 혼자서 뼈빠지게 일을 하다가 드디어 알바를 한 명 뽑았습니다.
IMG_PLACEHOLDER__image__SEP__https://firebasestorage.googleapis.com/v0/b/artico-app-4f9d4.firebasestorage.app/o/postImages%2F20250505%2F160229_26487_22387_186.jpg?alt=media&token=4f930030-c022-4599-a0b5-ebfc674fc7c1__END
이제 이 알바와 어떻게 일을 해야할까요?
알바에게 일을 시키는 의사소통 방법을 극단적으로 나눠보면 2가지가 있습니다.
첫번째, ‘버섯 불고기 그릴드 파니니’ 하나 만들어. 라고 원하는 결과물을 알려주는 방법이 있습니다.
두번째, ‘자, 먼저 냉장고에서 빵을 꺼내. 둘로 잘라. 그 다음 오븐에 구워. 여기다 소스를 바르고. 불고기를 100G 꺼내서…’ 라고 하나하나 과정을 알려주는 방법이 있습니다.
첫번째 방법을 ‘주문서’ 스타일, 두번째 방법을 ‘레시피’ 스타일이라고 해보겠습니다.
주문서 스타일은 일을 할 때 원하는 결과물만 알려줍니다. 그걸 ‘어떻게’ 만들지는 지시하거나 신경쓰지 않습니다. 알아서 하고 맛있는 그릴드 파니니만 나오면 되는 거죠.
레시피 스타일은, 일을 ‘어떻게’ 해야하는지를 세세하게 다 알려줍니다. 그릴드 파니니가 뭔지도 몰라도 돼요. 그냥 하나하나 시키는 대로 따라하고 나면 최종적으로 원하는 요리가 만들어집니다.
(이 2가지 스타일은 사실 식당이 아니라, 우리가 일을 하는 사무실에서도 늘상 볼 수 있죠. 어떤 사람이 말을 못 알아먹으면 레시피를 하나하나 가르쳐줘야 하고, 알아서 할 줄 알면 주문만 하면 되니까요)
당연하게도 이 2가지 스타일은 장단점이 있습니다.
주문서의 장점은 무엇일까요? 훨씬 간단하고 에너지가 덜 들죠. 하나하나 안 알려줘도 되고, 알아서 결과물만 가져오면 되니까요. 바꿔말하면 레시피의 단점이기도 합니다. 매번 레시피 스타일로 소통하다보면 ‘언제까지 내가 이런것도 알려줘야 해?’ 라는 생각이 들 수 있습니다.
레시피의 장점은 무엇일까요? 레시피는 에너지가 많이 드는 대신, 더 정확하고 세세한 컨트롤이 가능합니다. 그냥 ‘그릴드 파니니’라고 말했을 떄 나오는 결과물은 내가 기대한 것과 디테일하게 다를 수도 있어요. 그럴 때는 이걸 이렇게 하고, 이걸 이렇게 해서.. 레시피 방식으로 컨트롤을 할 수밖에 없습니다. 혹은 손님이 갑자기 메뉴에 없는 음식을 만들어달라고 했을 때, 그런 커스텀된 음식을 만들려면 레시피를 알려줄 수 밖에 없겠죠.
언어의 중요성주문서 방식에서는 ‘결과에 대해 소통할 수 있는 언어’가 중요합니다.
애초에 알바가 ‘그릴드 버섯 불고기 파니니’라는 게 정확히 무엇인지를 모른다면, 주문서 식으로 일을 할 수가 없습니다.
주문서 식으로 일을 하기 위해선, 메뉴, 프리셋, 템플릿.. 뭐라고 부르든 아무튼 ‘결과물’에 대한 명확한 정의가 있고 그 언어를 양쪽이 이해할 수 있어야 합니다.
나와 알바 사이에는 ‘그릴드 버섯 불고기 파니니’라는 언어가 어떤 결과물을 말하는 것인지 합의가 되어있고, 알바가 그릴드 버섯 불고기 파니니라는 결과를 만들기 위해 어떤 레시피와 절차를 거쳐야하는지 알고 있기 때문에, 우리가 굳이 하나하나 지시를 할 필요가 없는 것이죠.
이 ‘사전 합의된 언어’가 있다면, 이 언어로 표현가능한 영역 내에서는 이제 우리는 주문서 스타일로 편하고 효율적으로 커뮤니케이션을 할 수 있게 됩니다. ‘이거’하면 척하고 알아듣는다 이 말이죠. 훨씬 더 생산성이 높습니다.
컴퓨터와 일하는 2가지 방법그렇다면 프로그래밍 얘기로 돌아가보겠습니다. 프로그래밍은 결국 컴퓨터한테 일을 시키는 기술이거든요. 방금 예시에서 알바를 컴퓨터라고 생각하면 됩니다.
선언형 프로그래밍은 주문서 스타일로 코드를 쓰는 것이고, 명령형 프로그래밍은 레시피 스타일로 코드를 쓰는 겁니다. 결과는 ‘선언(declare)‘하고, 절차는 명령(imperative)합니다.
다시 말해 코드가 ‘원하는 결과’를 표현할 때 선언형,
결과를 어떻게 만들어야할지 ‘원하는 절차’를 표현하면 명령형이라고 합니다.
십수년 전의 UI 개발자들에게는 이 주문서 스타일 코딩이 절실했습니다.
그때 웹의 대세는 HTML, CSS에 JQuery 기술 조합이었는데요. 이 JQuery는 전부 다 레시피 스타일이었어요. 컴퓨터에게 시켜야 했거든요. 특정 id를 가진 섹션을 찾고, 박스를 추가하고, 아래로 10px 내리고, 타이틀에 ‘Hello world’라고 넣고… 이렇게 수십개의 절차를 거쳐야 하나의 UI가 나왔습니다.
이게 불편하니 개발자들은 주문서로 일하기를 바랬습니다. 즉, 우리가 원하는 ‘결과’를 컴퓨터에게 말하면 컴퓨터가 알잘딱깔센 해주기를 바랬던 겁니다.
하지만 아까 주문서 스타일이 되려면 뭐가 필요하다고 했죠? 결과물에 대해서 소통할 수 있는 언어가 필요합니다. 컴퓨터가 UI를 이해할 수 있는 언어가 필요했던 거죠.
그 과정에서 UI 언어 (흔히 디자인 컴포넌트, 디자인 시스템) 이라고 하는 것들이 발전하게 됩니다. 웹/모바일이 발전하면서 UI의 패턴이 어느 정도 성숙해졌고 자리를 잡았기 때문이죠.. 캐러셀, 아코디언, 카드, 뱃지 이런 말 들어보셨나요? 요런 게 다 흔히 쓰이는 UI 조각을 부르는 ‘언어’입니다.
이 때 뼛속부터 선언형인 리액트가 나타납니다. 리액트는 애초부터 모든 개발자들이 UI를 만들 때 먼저 컴포넌트라는 것을 정의하도록 합니다. 이 컴포넌트를 가지고 컴퓨터에게 UI를 어떻게 그릴지 알려주도록 합니다.
리액트에서는 타이틀에 텍스트 넣고, id넣고, 컬러 넣고 이렇게 코딩을 하지 않습니다. 대신 ‘타이틀’이라는 컴포넌트를 먼저 정의하고, React에게 ‘타이틀을 그려’라고 명령하는 스타일의 코딩을 하죠.
덕분에 코드만 봐도 이 코드의 결과물인 UI를 상상하고 이해하기가 쉬워졌습니다. 비슷한 UI라면 재사용을 할 수도 있었고요. UI 개발자들 특히 웹 프론트엔드에서는 이 방식으로 생산성이 굉장히 높아졌고, 리액트(+ 비슷한 선언형 UI 라이브러리들)가 엄청난 인기를 끌게 됩니다.
하지만 선언형도 단점이 없는 건 아닙니다.
첫째, 어쨌든 상호 정의된 프리셋 언어 위에서 주문하는 방식이다보니, 깊은 수준의 커스텀을 하기가 다소 까다로워집니다.
그냥 빈 캔버스에 막 그리는 것보다 레고 블록을 쌓아서 만들어야 하는 거잖아요? 만들 수 있는 결과물의 자유도가 좀 떨어지는 면이 있죠. 애니메이션 움직임이라든가 이런 고도의 커스텀이 필요한 것들은 선언형이 기본이라면 오히려 생산성이 떨어질 때도 있습니다.
둘째, 디버깅이 좀 어렵습니다.
내가 알바한테 ‘그릴드 버섯 불고기 파니니’를 달라고 했습니다. 근데 먹어보니 뭔가 맛이 이상합니다. 문제는 나는 주문만 했고, 얘가 어떤 절차로 그것을 만들었는지 모르기 때문에, 어떤 부분이 문제이고 뭘 고쳐야하는지가 명확하지 않다는 점이죠. 코딩에서도 굉장히 디테일하고 깊숙한 부분에 문제가 생기면 선언형의 경우는 디버깅하기가 까다로운 경우가 많습니다.
이 단점을 뼈저리게 느끼게 해준 것이 바로 애플의 선언형 UI 기술, SwiftUI입니다. 리액트의 선언형 스타일이 이미 대세가 되고 한참이 지난 2019년까지도 iOS의 주력 UI 기술 UIKit이라는 명령형 프레임워크였습니다. 그러다가 2019년 iOS는 뒤쳐지면 안된다고 느꼈는지 SwiftUI라고 하는 새로운 선언형 라이브러리를 내놓습니다. 이게 iOS의 미래라면서 엄청나게 홍보하고 난리 부르스를 쳤죠.
(그래서 제가 iOS 공부를 막 시작하던 시절에는 SwiftUI 배워야 하나요? 아니면 UIKit 배워야 하나요? 이런 질문이 진짜 수백번은 본 단골 질문이었습니다)
하지만 결론부터 말하면 SwiftUI는 나온지 6년이 된 지금까지도 큰 IT회사들에서는 아무도 안 쓰고 있습니다. 간단한 새로운 앱 만들 때는 이제 SwiftUI도 충분히 괜찮습니다. 하지만 큰 앱들은 대부분 SwiftUI 쓰는 걸 극도로 꺼립니다. UIKit 대세는 아직 깨질 기미가 보이지 않아요.
그 이유가 바로 자유도와 디버깅의 문제였습니다.
SwiftUI를 처음부터 완벽하게 잘 만들었으면 상관이 없겠는데, 애플이 처음 SwiftUI를 내놓은 3-4년 동안 SwiftUI는 자잘한 버그들이 많았습니다.
그러니까 내가 원하는 결과를 선언해도, 자꾸 이상한 동작들이 나오는 게 있었습니다. 절차에서 버그가 생긴거죠.
하지만 애플은 레시피 (절차) 절대 공개 안하기로 아주 유명한 회사입니다. iOS 개발자들은 애플 프레임워크 안을 절대로 들여다볼 수가 없습니다. 그러다보니까 겉에서 이렇게 넣어보고 저렇게 넣어보고 왜 이러지? 이러면서 디버깅을 해야하는데 아주 죽을 맛인 거죠.
99%에서 잘 작동하고 1%에서만 버그가 있더라도, 그 죽을 맛을 한번 본 iOS 개발자들은 다시는 SwiftUI 쪽으로 눈길도 돌리지 않았습니다. 특히나 대기업 앱일수록 안정성이 중요하니 더욱 그렇고요. 이제는 수년이 지나 그런 버그가 많이 개선되었다고 하는데, 이미 깨져버린 신뢰는 회복이 잘 안 되는 거죠.
게다가 제공하는 자유도도 굉장히 낮은 편입니다. 애플은 자기들이 생각하는 좋은 UI의 주관이 굉장히 쎄다보니, 자기들이 생각도 못해본 UI는 굉장히 부실하고 그걸 커스텀하는 것도 어렵습니다. 차라리 좀 복잡해도 내가 UIKit으로 직접 레시피 짜고 말지. 이런 생각이 드는 겁니다.
(말을 해놓고 보니 애플의 잘못이지 선언형의 단점을 아니라는 생각도 드네요..)
(+ 백엔드/서버 쪽은 어떨까요? 선언형 코드를 부분적으로 쓰지만 프론트엔드만큼은 아닌 것 같습니다. 백엔드에게 ‘결과물’이란 시각적인 UI보다는 이미 구조화된 데이터여서, 선언형이 주는 이점이 그렇게 크지 않을 수 있기 때문일지도)
쓰면서 사람 간 소통에까지 생각이 미쳤습니다. 조직 내에서 일을 할 때도 선언형과 명령형을 때에 맞게 쓰는 것이 참 중요합니다.
선언형으로 일을 하면 훨씬 더 자율적이고 유연하며 효율적이라는 장점이 있죠. 그러기 위해서는 우리가 결과에 대한 공통의 언어를 갖고 있는지, (흔히 말하는 ‘얼라인’이 잘 되어있는지)가 필수입니다. 원하는 결과대로 안 나왔을 때, 서로의 언어(기대치)를 조정해가는 피드백/튜닝이 꼭 필요하고요.
하지만 아예 일의 결과물이 반복적이지 않거나, 언어로 표현하기 어려운 자유도를 갖고 있다면. (예를 들어 음악이나 광고나 영화 같이 언어의 해상도보다 훨씬 더 높은 결과물) 오히려 명령형이 더 효율적일 수도 있다는 생각도 들었습니다.
예전 제가 리디에서 웹툰을 기획할 때, 웹툰 작가들과 소통을 할 때 정말 힘들었던 경험이 떠올랐습니다. 저는 전문가가 아니니. 당연히 이런 결과물이 나왔으면 좋겠다고만 말하고 실제 연출이나 콘티는 주문하지 않았었는데, 막상 그 분이 그려온 것은 제 생각과 전혀 다른 그림이었어요. 근데 내가 원하는 것을 언어로 표현하기는 너무 어렵고. 결국은 하나하나 세세하게 여기는 좀 더 크게, 여기는 이런 샷으로.. 하나하나 설명해서 피드백을 드렸던 기억이 납니다. 이런 건 주문형을 할래도 하기가 어렵더라고요. 아예 그냥 작가한테 다 믿고 맡기는 크리에이터 중심형이나, 아예 공장식으로 기획서와 콘티와 작업지시서를 만드는 방식이 업계에 둘다 존재했던..
아무튼 정리하자면,
-
일을 시킬 때 결과를 말하는 주문서 방식이 있고, 과정을 말하는 레시피 방식이 있다.
-
프로그래밍에서는 주문서 방식을 ‘선언형’이라고 하고, 레시피 방식은 ‘명령형’이라고 한다.
-
선언형으로 소통하기 위해서는 ‘결과에 대한 공통의 언어’가 합의되어야 한다.
-
UI 개발 쪽에서는 생산성과 효율성이 높은 선언형이 확실한 대세가 되었다.
-
하지만 자유도와 디버깅 측면에서는 절차형이 낫고 여전히 둘 다 필요하다.
-
인간 조직에서도 상황에 따라 선언형 소통과 명령형 소통이 둘 다 필요하다.