
제목
언어 탓하지 말라던 내가, 사내 공통 라이브러리를 만들다 3주를 날린 이유
본문
솔직히 고백하자면, 스타트업에서 '야생형 개발자'로 구르던 시절 저는 프로그래밍 언어론을 이야기하는 사람들을 조금 한심하게 봤습니다. "언어가 뭐가 중요해? 라이브러리 잘 갖다 쓰고, 비즈니스 로직 빨리 짜서 배포하는 게 장땡이지." 이게 제 지론이었거든요. 당시 저는 파이썬(Python)과 장고(Django)를 쓰고 있었고, 프레임워크가 제공하는 '마법' 같은 생산성에 취해 있었습니다. C++로 템플릿 메타프로그래밍을 논하거나, 하스켈(Haskell)의 모나드(Monad)를 이야기하는 개발자들을 보면 "저런 걸 알아서 당장 서비스 출시에 무슨 도움이 되지?"라고 생각했죠.
최근 대기업으로 이직하고 나서, 그 오만함이 얼마나 부끄러운 것이었는지 뼈저리게 깨달았습니다. 팀 내 생산성을 높이겠다며 의욕적으로 '사내 공통 로깅 라이브러리' 개발에 자원했다가 거하게 삽질을 했거든요.
당시 저는 동적 타이핑 언어에서 흔히 쓰던 '데코레이터'나 '메타프로그래밍' 패턴을, 정적 타입이 강한 자바(Java) 기반의 레거시 시스템에 그대로 이식하려 했습니다. "파이썬에서는 어노테이션 하나면 끝났는데, 왜 여기선 안 되지?"라며 애먼 언어를 탓했죠. 결국 리플렉션(Reflection)을 남발하고, 제네릭(Generic)으로 범벅이 된 괴물 같은 코드를 만들어냈습니다. 동료들이 PR(Pull Request) 리뷰에서 "이거 디버깅은 어떻게 하나요?", "컴파일 타임에 안전한 거 맞나요?"라고 물었을 때, 저는 식은땀을 흘리며 아무 말도 할 수 없었습니다. 3주간의 작업물은 결국 폐기되었습니다.
그 참담했던 실패 후, 우연히 읽게 된 2016년의 한 아티클이 제 머리를 강하게 때렸습니다. 패트릭 리(Patrick Li)가 쓴 글이었는데, 내용인즉슨 그의 친구가 "언어는 중요하지 않다. 루비(Ruby) 언어 자체는 별로지만 레일즈(Rails)가 있어서 쓴다"라고 말했다는 겁니다. 저랑 똑같은 생각을 가진 친구였죠.
하지만 저자는 여기서 정곡을 찌릅니다. "왜 자바(Java)나 C에는 레일즈만큼 쉽고 강력한 웹 프레임워크가 없을까? 자바 개발자가 무능해서? 아니다. 언어가 그걸 허락하지 않기 때문이다."
망치로 얻어맞은 기분이었습니다. 레일즈가 제공하는 그 환상적인 생산성, 즉 "설정보다 관례(Convention over Configuration)"라는 철학이 구현될 수 있었던 건, 루비라는 언어가 메타프로그래밍과 블록(Block), 동적 타이핑을 지원했기 때문입니다. 반면, 과거의 자바는 일급 함수(First-class Function)조차 없었기에 버튼 클릭 이벤트 하나를 처리하려고 해도 거대한 익명 클래스를 만들어야 했죠. 언어의 설계가 라이브러리의 설계 한계를 결정짓고 있었던 겁니다.
제가 실패한 이유도 정확히 여기 있었습니다. 저는 자바라는 언어가 제공하는 '재사용 메커니즘'의 특징(인터페이스, 엄격한 타입 시스템)을 무시한 채, 다른 언어의 패러다임을 억지로 끼워 맞추려 했던 겁니다. 마치 트럭을 스포츠카처럼 몰려고 했던 셈이죠.
이 깨달음은 지금 제 개발 인생의 2막을 열어주었습니다. 이제 저는 새로운 라이브러리나 프레임워크를 도입할 때, 단순히 "사용법"만 익히지 않습니다. "이 라이브러리 제작자는 왜 이런 인터페이스를 만들었을까? 언어의 어떤 기능을 활용해서 이 복잡성을 추상화했을까?"를 고민합니다.
예를 들어, 요즘 코틀린(Kotlin)으로 마이그레이션을 하면서 코루틴(Coroutines)을 도입하고 있습니다. 예전 같으면 "그냥 비동기 처리하는 거네" 하고 넘겼겠지만, 지금은 이것이 '콜백 지옥'을 언어 차원에서 어떻게 '순차적 코드'처럼 보이게 만드는지, 그 내부의 컨티뉴에이션(Continuation) 스타일을 이해하려 노력합니다. 그래야만 트래픽이 몰려 스레드 풀이 고갈되는 상황에서 멍하니 모니터만 바라보는 실수를 하지 않으니까요.
최근 화두가 되는 AI 코딩 도구(Cursor, Copilot 등)를 쓸 때도 마찬가지입니다. AI는 코드를 뱉어낼 뿐, 그 코드가 우리 시스템의 아키텍처와 언어적 특성에 맞는지 판단해 주지는 않습니다. 언어의 제약과 가능성을 이해하는 개발자만이 AI가 짜준 코드를 '동작하는 쓰레기'가 아닌 '유지보수 가능한 자산'으로 만들 수 있습니다.
혹시 지금 "언어 공부할 시간에 기능 하나 더 만들지"라고 생각하는 주니어 분들이 계신다면, 잠시 멈춰보세요. 우리가 누리는 편리한 라이브러리는 모두 그 언어의 한계와 가능성 위에서 춤을 추고 있는 결과물입니다. 그 무대의 구조를 이해하는 순간, 여러분은 단순히 라이브러리의 '사용자(User)'를 넘어, 진짜 문제를 해결하는 '설계자(Architect)'로 성장할 수 있을 겁니다. 저처럼 3주를 날려먹고 나서 깨닫지 않기를 바라며, 오늘 퇴근길에는 여러분이 쓰는 주력 언어의 철학을 다룬 책을 한 번 펼쳐보는 건 어떨까요?


