관계지향 프로그래밍
<맹자> 에는 불인인지심(不忍人之心)에 대한 이야기가 나온다. 불인인지심이란 사람이 본래 가지고 있는 선한 마음을 말한다. 춘추전국시대 제나라의 군주인 제선왕의 고사에서 유래한 이야기다.
하루는 제선왕이 대전에 앉아있는데, 어떤 사람이 대전 아래로 소를 끌고 지나갔다. 왕이 그것을 보고 "그 소를 어디로 끌고 가느냐?"고 묻자 그 사람은 "혼종(제물)에 쓰려고 합니다"라고 대답했다. 그러자 제선왕은 "그 소를 놓아주어라. 부들부들 떨면서 죄 없이 도살장으로 끌려가는 모습을 나는 차마 보지 못하겠다"라고 하였다. 그러자 그 사람이 대답하기를 " 그러면 혼종 의식을 폐지할까요?"라고 하자, 왕은 "혼종을 어찌 폐지할 수 있겠느냐. 소 대신 양으로 바꾸어라"고 하였다. 많은 사람들이 이 이야기를 듣고 소와 양이 뭐가 다를게 있냐며 제선왕을 비난했다. 이에 대한 맹자의 의견은 다음과 같았다.
"왕께서 하신 일이 바로 인(仁)의 실천입니다. 소는 보았으나 왕을 보지 못했기 때문입니다."
소와 양에 대한 처리가 다를 수 있었던 이유는 관계에 있다. 핵심은 보았느냐, 보지 못했느냐이다. 본다는 것은 만남을 의미하고, 만남은 관계가 형성된 것을 의미한다. 서로 보지 못하고 알지 못하는 관계에서는 불인인지심이 발휘되기 어렵다. 악덕업자가 소비자들이 먹는 식품에 몸에 좋지 않는 성분을 거리낌없이 넣을 수 있는 이유도 마찬가지다.
서로가 보기 어려운 이 시대, 코로나가 만들어낸 비대면 생활양식은 많은 것들을 바꿔놓았다. 그렇지 않아도, 메타버스와 같은 가상현실과 증강현실 기술의 발전으로 언택트(Untact) 문화는 우리의 삶에 그 지반을 넓히는 중이었다. 그러던 중 느닷없이 찾아온 100나노미터밖에 되지 않는 불청객으로 인해 인류의 생활양식은 때이른 일대 전환을 맞이하게 되었다. 재택근무나 화상회의가 일상이 되었다. 메신저로 업무를 논의하고 클라우드로 모든 데이터와 업무자료를 주고받는다. 소스코드를 수정해서 시스템에 업로드하면 자동으로 분석과 빌드, 테스트가 이루어지고 소프트웨어 배포까지 일사천리로 진행된다. 모든 소통과 연결이 네트워크를 통해 디지털로 이루어지는 이 시대에 대면 소통과 대화는 얼핏 불필요해 보이기까지 하다.
하지만 우리가 하는 거의 모든 일들은 연결과 소통을 필요로 한다. 비대면이라 하더라도 소통의 끝과 끝에는 사람과 사람이 있다. 언택트 문화가 고착화됨으로 인한 부작용 중의 하나는 디지털과 네트워크 그 건너에 있는 사람의 존재에 대해 무감각해질 수 있다는 것이다. 불인인지심이 발휘되기 어려운 상황인 셈이다. 언택트 업무 프로세스에서 의사소통과 피드백은 직접 대면할 때보다 더 빠르게 이루어진다. 이는 고도로 갖춰진 업무 환경 덕분이다. 하지만 인간적인 소통은 사라지고 있다. 남들로부터 받아들이는 것들에는 엄격하면서 정작 다른 이들에게 내보내는 것들에는 배려가 결여되어 있다.
온라인으로 다른 개발자들과 협업을 하다 보면 흔히 생기는 상황 중의 하나가 ‘한쪽에서는 되는데, 다른 한쪽에서는 되지 않는’ 문제다. 코드를 구현하고 프로그램을 빌드해서 문제없이 동작하는 것을 확인하고 코드나 라이브러리를 시스템에 업데이트한다. 해당 업데이트를 적용한 다른 개발자가 문제가 있다는 리포트를 보내온다. 자신의 개발환경에서 재차 확인해보지만 아무런 문제가 보이지 않는다. 그래서 이렇게 얘기한다.
“제 쪽에서는 아무런 문제가 없는데요?”
그럼 상대방은 이렇게 응수한다.
“(그건 모르겠고) 제 쪽에서는 문제가 있는데요?”
분명 문제는 둘 중 하나에 있다. 다른 쪽에서의 문제를 해결해주기 위한 노력이 아닌, 자기 쪽에 문제가 없다는 것을 증명하려는 노력이 우세할 때 결국 개발 프로젝트는 산으로 간다.
인간은 HELF이라고 써 있어도 HELP라고 인지한다. 흔히 ‘유도리’라는 말을 쓴다. 일본어 유토리에서 온 단어인데, 융통성을 의미한다. 개떡같이 말해도 찰떡같이 알아먹는다는 건데, 소프트웨어도 이런 융통성이 있는 소프트웨어가 좋은 소프트웨어다. 소프트웨어에서는 이런 융통성을 로버스트니스(robustness)라고 한다. robustness는 영어단어 뜻으로는 견고함이나 강건함으로 풀이가 되는데, 소프트웨어가 robustness하다는 것은 그 동작이 경직되어 있지 않고, 여러 상황에 잘 대응이 되는 것을 의미한다.
대표적인 네트워크 전송 프로토콜인 TCP/IP는 이런 융통성이 잘 고려된 기술이다. TCP의 초기 모델은 미국의 컴퓨터 과학자인 존 포스텔이 개발했다. 존 포스텔은 TCP모델을 설계할 때 견고함의 원칙(robustness principle)이라는 것을 도입했다. 이 견고함의 원칙은 "자신이 행한 일은 엄격하게 하고, 남에게 받는 것은 너그럽게 받는 것"이다. 외부로 전송하는 데이터는 사전에 정해진 규약에 따라 확실하게 데이터를 갖춰서 내보내고, 외부로부터 받는 데이터는 그 의미만 명확하다면 조금 명세에 어긋나더라도 융통성 있게 포용하는 것이다. 자신에게 엄격하지만 남들에게는 너그러운 것 - 이것은 똘레랑스(tolerance), 즉 관용의 법칙과 같다. tolerance 역시 소프트웨어에서 많이 사용되는 개념으로 tolerance가 부족하면 부족할수록 소프트웨어의 경직도는 증가한다.
포스텔의 TCP모델에서 채택한 장애 허용 시스템(Fault tolerance system) 때문에 인터넷 통신은 더 활발하고 안정되게 이루어질 수 있었다. 포스텔이 명명한 이 견고함의 원칙은 다른 소프트웨어 분야에도 큰 영향을 주었다. 그 영향을 받은 대표적인 프로그래밍 언어가 오랜 기간 웹개발을 지배해온 HTML과 CSS다. 이 언어들은 관용적인 오류처리구조를 가지고 있다. 이는 여러 다른 종류의 인터넷 브라우저와 서버 시스템 간의 호환성을 증대시켰다.
외부로 나가는 소통을 명료하게 하는 것, 그리고 외부로부터 받는 소통에 있어 최대한의 융통성과 관용을 보이는 것, 이 두가지를 두 글자로 표현하면 바로 '배려'다. 개발 커뮤니케이션이든 일반적인 커뮤니케이션이든 가장 중요한 것은 배려다. 나보다 남을 먼저 생각하는 것이 배려다. 자신의 하는 일에 대해서는 높은 기준을 세우고, 다른 이들에게는 보다 유연하고 관용적인 기준을 적용하는 것이다. 이것이 개발의 세계에서 타자와의 관계에서 발휘해야만 하는 인간 본연의 불인인지심이다. 물론 쉽지 않다. 그렇지만 어려운 만큼 가치가 있다. 그럼 개발자들이 불인인지심을 발휘해야 하는 가장 기본적인 활동은 무엇인가?
코딩 역시 일종의 커뮤니케이션이다. 머신이나 컴파일러와의 커뮤니케이션에만 치중하는 것은 1960년대 개발방식이다. 1960년대 매사추세츠공과대학(MIT)에서 시작된 해커문화는 소프트웨어의 발전에 큰 영향을 주었다. 여전히 해커문화를 동경하는 개발자들이 많다. 60, 70년대 미국의 해커들은 컴퓨터로 예술을 할 수 있다고 믿었다. 그들에게는 코드 자체가 예술이었다. 하드웨어를 최적으로 제어하기 위해 코드는 괴상망측하게 만들어져도 아무 상관이 없었다. 지금과는 비교도 할 수 없이 열악한 컴퓨팅 성능을 뽑아내기 위해 해커들은 모든 노력을 쏟아 부었다. 메모리를 가능한 적게 사용하고, 동일한 컴퓨터로 다른 해커의 프로그램보다 더 빨리 동작할 수 있는 코드를 만들어내는 것이 지상 최고의 과제였다. 최대한 어셈블리 명령어를 적게 써서 동일한 기능을 더 빠르게 구현하려는 시도들로 인해 알고리즘이 발달했다. 모든 코드는 공유되었기에 해커들은 다른 해커가 짜 놓은 코드를 보면서 감탄하고 그 안에서 예술과 아름다움을 발견했다. 그들만의 세상이었다. 자기 코드에 주석을 달아놓는 해커는 거의 없었다. 프로그램은 더 빠르고 더 효율적으로 작동하면 그만이었다. 코드가 복잡하면 복잡할수록 프로그램의 성능은 높아졌고 이것이 코딩 예술의 척도가 되었다. 즉, 프로그램의 예술과 미는 해커만이 알 수 있는 전유물이었고, 코딩은 완벽하게 컴퓨터의 관점만을 반영했다. 1960년대 초 MIT에 입학한 스튜어트 넬슨은 이런 해커 중에서도 최고의 천재 해커였다. 스티븐 레비는 그의 책 <해커스>에서 스튜어트 넬슨과 다른 천재 해커였던 에드 프레드킨과의 일화를 묘사한 바 있다.
스튜어트 넬슨은 최대한 빠르게 낙서하듯 프로그램을 적으며 혼자 달려나갔다. 프레드킨은 마침내 호기심을 못 이기고 넬슨이 짠 프로그램을 들여다보았다. 믿을 수가 없었다. 코드는 괴상했다. 무슨 소린지 감도 안 오는, 하위 루틴들이 얽히고 설킨 미친 조각처럼 보였다. 그럼에도 불구하고 코드가 돌아가리라는 사실은 명백했다. 프레드킨은 참지 못하고 소리쳤다.
"스튜! 도대체 왜 이렇게 짜지?"
넬슨은 예전에 PDP-6에서 비슷한 프로그램을 짰다고 설명했다. (중략) 넬슨은 머릿속으로 기계어 명령어를 그대로 압축하는, 그래서 작업 결과물을 최소로 줄이는 경지에 이르렀던 것이다.
이제 이런 코딩은 거의 필요 없는 시대다. 아니, 오히려 나쁜 코딩이다. 다른 개발자가 전혀 건드릴 수 없지만 완벽하게 동작하는 코드라면? 그건 하드웨어지, 소프트웨어가 아니다. 프로그래밍 언어는 기계를 동작시키기 위해 탄생했으나 현재 대다수의 개발자들이 쓰고 있는 프로그래밍 언어는 기계의 존재에 무관하다고 볼 수 있다. 그래서 프로그래밍 언어 역시 사람들을 위한 언어와 다르지 않다. 프로세서의 성능이 떨어지고 메모리용량이 수 KB밖에 되지 않던 시절에는 작고 최적화된 코드를 쥐어짜내기 위해 개발자들 역시 머리를 쥐어짜내야만 했다. 1960~70년대뿐만 아니라 저사양 임베디드 소프트웨어 산업군에서는 근래까지도 유효했던 코딩 패러다임이었다. 하지만 시대가 변했다. 코드 최적화는 사람보다는 기계가 훨씬 더 잘한다. 그리고 머리를 쥐어짜서 얻을 수 있는 프로세서의 성능개선과 메모리의 비용 역시 미미하다. 이제 기계에 대한 배려보다는 사람에 대한 배려가 필요하다. 잘 돌아가기만 하는 코드를 넘어서 잘 사용할 수 있는 코드가 좋은 코드다.
코드의 명료함과 가독성을 높이고, 예외처리에 주의하는 등의 활동은 비단 소프트웨어의 품질만을 높일 뿐 아니라, 함께 일하는 개발자들을 배려하는 것이다. 이것이 곧 관계지향 (relationship-oriented)프로그래밍이다. 배려하면서 살자. 인간(人間)이라면 그래야 한다. 사람과 사람 사이 기계가 아닌 사람이 있다.
** 2022년 4월 교보문고 리드잇 매거진에 기고한 글입니다.
http://www.yes24.com/Product/Goods/108462627