코드 읽기
Reading Code Is A Skill
발단은 이렇다. 누군가 “방대한 코드가 읽기 너무 어려워요”라는 글을 올렸는데, 거기에 “그 코드를 거지같이 짜놔서 그래요”라는 답변을 보고 동의하기 어려웠고, 그 이유를 생각하다보니 한번 쯤은 정리하면 좋을 것 같아서 쓰게 되었다.
나의 롤 모델 중 한명인 Yaron Minsky가 언젠가의 톡에서 했던 말이 있다: “우리는 코드를 짜는 것보다 훨씬 더 많이 코드를 읽는다.” 아주 당연하지만 중요한 사실이다. 직업 소프트웨어 엔지니어로서, 우리는 코드를 작성하는 양보다 훨씬 많은 양의 코드를 읽게 된다. 아니 읽어야만 한다. 안그럼 코드를 어떻게 짜.
관련해서 내가 평소에 생각하던 두 가지가 있는데,
- 읽기 좋은 코드(readable code)라는 것은 주관의 영역이다.
- 코드가 작성된 시점과 읽는 시점 사이에는 시차가 존재한다.
1은 논쟁의 여지가 없다고 생각한다. 나는 파스칼 케이스가 싫고, 스네이크 케이스가 좋다. 변수에 쓰일 단어를 줄이기보다는 최대한 풀어 쓰는게 좋다. 타입을 생략하기보다는 확실하게 적어주는게 좋다. 등등, 이 부분은 분명히 주관이 강하게 개입하는 영역이기 때문에, 내가 아닌 다른 사람이 짠 코드에 대해서 함부로 거지같이 짜놨다고 말할 수 없다. 그냥 호불호가 있을 뿐.
2는 예전 커밋 메시지 잘 적기 포스팅 중 일부와도 관련이 있는데,
혼자 개발하는 개인 프로젝트마저도 협업이 필요 없어 보이지만, 오늘의 나와 몇 달 후의 나는 (거의) 다른 사람이다. 일단 옛날 커밋과 관련된 문맥을 (거의 다) 잊어버릴 게 분명하다.
그러니까, 분명한 시차가 존재한다. 사실 시차말고 더 좋은 단어가 있으면 좋겠는데, 아무튼. 코드를 작성했던 시절의 나는 그 언어를 잘 몰랐거나, 코딩 스타일이라던가 일관된 네이밍 룰에 관심이 없었거나, 그 때는 최선이라고 생각했었는데 시간이 흘러 코드를 읽는 지금의 최선과는 거리기 멀거나, 그 때는 하드웨어가 지원하지 않는 연산을 해킹했었는데 지금은 그럴 필요가 없어졌다거나… 이런 다양한 것들 말이다. 프로그래밍은 시간이라는 요소가 분명한 영향을 미치는 작업이다.
그렇기 때문에, “코드를 거지같이 짜놔서”라는 단순한 이유에는 동의하기가 어려웠다. “거지같음”은 주관의 영역이고, 실제 그 코드가 작성된 시점에는 오히려 그 “거지같음”이 최선의 선택이었을지도 모를 일이니까.
그러다가 마침 코드를 읽는 것도 스킬이다라는 포스팅을 접하게 되었는데, 굉장히 동의하는 내용이 많아서 인상 깊었던 글귀를 정리해보았다.
이 글의 발단은 이거다. “코드를 짜는 것보다 훨씬 더 많이 읽게 될테니, 코드를 잘 읽는 방법을 배우자”는 글을 썼더니, 많은 사람들이 “아니다, 코드를 읽기 좋게 짜는 방법을 배워야 한다!”라고 대응하고 있다.
사람들의 반응이 이해가 안가는 것은 아니다. 하지만 저자가 말하고자 했던 점은 “코드를 잘 읽는 방법을 배워야한다”이지, “코드를 읽기 좋게 짜면 안된다”가 아니다. 당연히 읽기 좋은 코드를 짜야 한다. 근데 이 두 가지는 상호배타적이지 않다. 즉, “읽기 좋은 코드 짜기” 또는 “코드 잘 읽는 법 배우기” 둘 중 하나를 선택하는 문제가 아니라는 거다. 이건 마치, “나는 연비운전 할 거니까 차에 기름 안넣어도 돼~”라고 말하는 거랑 비슷하다. 아무리 연비운전을 해도 언젠가는 차에 기름을 넣어야 한다.
“그냥 읽기 좋은 코드를 짜세요”의 문제는 세 가지다.
1. 누군가 “읽기 힘든” 코드를 (일부러) 짰을 거라는 것은 잘못된 생각이다.
읽기 힘든(unreadable) 코드는 어쩌면,
- 지금의 언어/프레임워크같은 게 없을 때 짰거나,
- 그 당시의 “모범 사례(best practice)”가 지금과는 달랐거나,
- 처음에는 읽기 쉽게 짰지만 시간이 지나고 코드가 추가되면서 원래의 가독성을 옅어졌거나,
- (그 코드를 작업하던)사람들이 계속 이직해서 코드 뒤에 숨어있는 업무적/기술적 이유를 물어볼 사람이 없거나,
… 등등의 이유가 합쳐진 결과일 수 있다.
일부러 읽기 힘든 코드를 짜는 사람은 아무도 없다. 나만 작업하는 프로젝트일지라도, 나중에 시간이 지나고 다시 보면 같은 일을 하는 훨씬 더 좋은 방법을 떠올릴지 모른다. 심지어 나는 자주 이런다. 🥲
2. 코드 짠 사람을 탓하기만 하는 건 아무런 문제를 해결하지 못한다.
사실 이 글귀에 감명을 받아서 이 글을 쓰게 되었다.
“코드를 읽기 힘든 이유는 짠 사람의 잘못이기 때문에, 당신은 읽기 좋은 코드를 짜야 한다” 라는 이야기는 언뜻 그럴싸하지만, 문제를 해결하는데는 전혀 도움이 되지 않는다. 그저 상황을 탓할 뿐이다. 코드를 나쁘게 짠 사람을 탓하고, “앞으로 읽기 좋은 코드를 짜야지!”하고 다짐하기는 쉽다. 반면 이런 생각은 치워두고, “그래, 지금 해야 할 일은 이 코드 베이스에 있는 새로운 사투리(?)를 배워서, 의도가 뭔지 해석하는 거야.”로 가는 일은 훨씬 어렵다. 그냥 불평하기만 해서는 아무것도 해결하지 못한다.
그러니까 이런 거다. 셰익스피어의 희곡은 고전 영어로 쓰여있기 때문에 현대인의 눈에는 읽기 힘든 글일 수 있다. 그렇다고 “셰익스피어가 더 잘 썼어야지” 로 끝나 버렸다면, 우리는 로미오와 줄리엣이라는 작품을 알지 못했을 것이다.
3. 읽기 좋은 코드라는 것은 주관적이다.
이건 뭐 너무나 당연하다. 저자는 코드의 가독성이란 “읽는 사람의 누적된 경험“이라는 아이디어를 제시한다. 자바만 짜던 사람한테 모던 자바스크립트 프로젝트를 읽으라고 하면 아마 꽤 고생하지 않을까? 당장 나도 로우 레벨 Rust 코드를 읽으려고 하면 한 세월이 걸릴 것이다.
코드 읽기는 기술이다.
그러니까, 코드를 읽는 것도 학습하고 개선할 수 있는 기술이다. 다양한 언어, 프레임워크, 라이브러리, 코드 베이스, 프로그래밍 스타일, 디자인 패턴에 쏟은 시간, 경험, 연습은 코드를 읽는 능력을 키워줄 거다. 사실 직업 프로그래머로서 그냥 일만 해도 코드를 많이 읽기 때문에 늘긴 할 거다. 하지만 이걸로는 충분하지 못하고, 여기서 “의도적인 수련(deliberate practice)”의 개념이 소개되는데, 이거는 관련된 책을 읽고 난 이후에 다시 정리해 봐야겠다.
그럼 코드를 잘 읽으려면 어떻게 해야 할까? 사실 나도 잘 모르겠다. 세상엔 모르는 게 너무 많다. 그렇지만 지금까지 해왔던 걸 떠올려보니, 세 가지 마음가짐이 정리되어서 기록해둔다.
1. 프로그램의 목적이 뭔지 확실하게 알아야 한다.
예를 들어 지금 이 글을 쓰고 있는 프로젝트의 코드는 모두 “블로그”라는 웹 서비스를 호스팅하기 위한 코드들이다. 이걸 아는 것과 모르는 것은 코드를 읽는 데에 있어서 꽤 큰 차이를 주는 것 같다.
그러니까, 나침반이나 지도에 비유할 수 있겠다. 한 번도 안가본 곳을 찾아갈 때, 제대로 가고 있는지 확인하면서 가는 게 좋지 않을까? “대충 이 근처에 있겠지”하면서 가는 거랑, 지금 올바른 방향으로 가는 것인지 확인하면서 가는 거랑은 아주 다를 것이다.
2. 작업과 관련 있는 부분을 먼저 빠르게 읽고 파악한다.
이건 1을 전제로 했을 때의 얘기다. 일단 프로그램의 목적이 뭔지 확실히 알고 나서, 그 목적 하에 내 작업과 관련있는 부분을 파악해 가는 것이다. 여기에는 각종 라이브러리 코드, 테스트 코드, 배포 관련 코드 등이 포함될테니, 놓치지 않고 잘 따라가는 것이 중요하다.
따라가다 보면 (지금의) 내가 보기에 이상하게 느껴지거나, 마음에 안들거나, 그래서 당장 수정하고 싶은 부분들이 생길텐데, 긴급한 수정이 필요하거나 코드를 따라가는 데에 문제가 있는게 아니라면 일단은 그냥 놔두자. 나중에 수정해도 된다. 우선은 일부라도 확실하게 파악하는 것이 중요하다. 그렇게 얻은 자신감을 가지고 계속 읽어야 한다.
3. 시간이 필요하다. 조급해하지 말자.
수 천 ~ 수 만 줄이 되는 코드 베이스 전체를 하루아침에 다 읽고 이해하기란 불가능에 가깝다. 하루 8시간이라는 긴 시간을 오롯이 “코드 읽고 이해하기”라는 하나의 작업에 집중할 수 있는 사람은 드물다. 그리고 코드만 읽어서는 이해하기 어려운 부분도 있다. 프로그램의 목적과 관련있는 도메인 지식을 공부해야 할 때도 있고, 코드 베이스가 작성된 시점과의 시차도 따라 잡아야 하고, 프로젝트에 따라서는 프로그램이 실제 사용되는 현실을 알아야 하는 경우도 있다. 하지만 이 모든 것은 (내가 적절한 방향으로 노력한다는 가정 하에) 모두 시간이 해결해주리라 믿는다. 위대한 폰 노이만도 비슷한 맥락에서 “(수학에서는) 이해하는게 아니라 익숙해지는 거다”라는 얘기를 한 적이 있는데, 익숙해지는 데에는 시간을 쏟는 게 가장 좋은 방법 아닐까?
“코드 읽기”에 대한 생각을 정리해보았다. 다른 곳에도 적용할 수 있는 생각들이 정리된 것 같다. 은총알처럼 한방에 해결할 수 있는 마법같은 기술을 나는 아직 찾지 못했다. 다른 사람들은 코드를 어떻게 읽고 있는 걸까? 나는 제대로 하고 있는 걸까? 시간을 들여서 많은 공부를 하다 보면 언젠가는 도달하게 되는 경지가 있는 걸까? 알 수 없다. 지금은 그저 내가 가는 방향이 옳기를 바랄 뿐이다.