프로그래밍 심리학을 읽고 - 1

최근 방을 정리하다 책장에서 제럴드 와인버그가 쓴 프로그래밍 심리학이라는 책을 발견했습니다. (제가 산 책은 아닐테니, 아마 동생이 사둔 책으로 추정됩니다.) 1971년 초판이 출간된 이 책은 어느덧 올해로 40살이 된 책입니다. 기술을 다루는 책이었다면 아마 버렸겠지만, 이 책은 그 기술을 다루는 인간에 좀 더 초점을 맞추고 있습니다. 실제로 쭉 읽으면서 40년 전이나 지금이나 프로그래밍은 기술만 달라졌지, 전반적으로 비슷하다는 인상을 받았습니다. 저자의 말을 빌리자면 “기술은 아닐지도 모르지만, 인간의 행동에는 좀처럼 변하지 않는 어떤 일관성이 있는 것” 같습니다.

오늘은 책의 1부인 인간 행위로서의 프로그래밍을 요약하고 느낀 점을 이야기해보겠습니다. 참고로 아래 두 소제목 외에도 “프로그래밍이란 행위를 연구할 방법은 무엇인가?”가 있었지만, 개인적으로는 그렇게 흥미가 있는 분야는 아니라, 이 글에서는 다루지 않았습니다.

프로그램 읽기

어떤 프로그램이 현재의 모습을 갖게 된 데에는 다 이유가 있다. (43p)

마지막으로 다른 사람의 프로그램을 읽은 게 언제였나요? 다른 사람의 코드를 읽는 일은 쉽지 않은 일입니다. 이해력이 부족해서 일 수도 있지만, 가끔은 아무리 생각해도 왜 이렇게 작성했는지 모를 코드를 마주할 때가 종종 있었습니다. 그러나 저자는 모든 코드에는 이유가 있다며, 어떤 한계가 오늘의 모습을 만들었을지 생각해보길 권합니다.

먼저, 기계의 한계가 문제가 될 수 있습니다. 예를 들어 주 메모리 용량이 충분하지 않다면, 보조 메모리를 활용하는 방식의 코드를 작성했을 것입니다. 이는 메모리가 풍족한 오늘날에는 이해할 수 없는 코드일 수도 있습니다. 또한, 언어의 한계가 문제가 될 수 있습니다. 현재 버전에서는 너무 당연하게 지원하는 것을 이전 버전에서는 지원하지 않아 패키지나 라이브러리를 직접 구현하는 경우도 있었을 것입니다.

여기에 더 나아가 저자는 인간적인 한계들을 강조합니다. 프로그래머의 한계 역시 문제가 됩니다. 사람들이 가장 간과하기 쉬운 부분이라고 저자는 말합니다. 실제로 이러한 한계들이 해결된 이후에도, 프로그래머는 알지 못했기 때문에, 혹은 익숙한 방식을 고수하고자 코딩을 할 수도 있습니다. 그리고 가장 눈에 띄지 않는 것이 바로 외부 상황의 한계입니다. 이 책은 입력 카드(!)의 특정 위치에 A라는 문자가 있으면 그것을 1로 치환하는 알 수 없는 코드로 그 예시를 듭니다. 사실 이는 특정 지역의 천공기에만 생긴 문제 때문에 구현된 임시 방편용 코드였으며, 이러한 코드는 간단히 알아보기 쉽지 않을 것입니다. 이 외에도 일정의 문제로 특정 기능을 제대로 구현하지 못한 더미 코드들도 예시에 속할 수 있습니다.

제일 처음 팀에 합류하여 기능을 개발하던 때가 생각납니다. 레거시 애플리케이션에 새로운 기능을 추가하는 일이었는데, 해당 코드를 작성했던 분들이 한 분도 남아있지 않아 고생을 많이 했던 일이 생각났습니다. 그때는 ‘처음이라 힘든 거야’라고 생각했지만 아마 그 당시 제가 많이 고생했던 이유는 코드의 각 부분이 왜 이렇게 작성되어 있는지에 대한 정확한 답을 얻을 수 없었기 때문이라고 생각합니다. ‘왜 사용하지 않는 Test가 남아있을까?’, ‘이 기능은 왜 이렇게 작성하셨을까?’ 같은 고민. 그 모든 맥락을 이해할 수 없다 보니 새로운 기능을 추가하는 일이 처음에는 아주 두려웠습니다. 돌이켜보면 그런 이유를 너무 기계적, 혹은 언어적 한계에만 치우쳐서 생각했던 것은 아닌가 반성해봅니다. 앞으로 레거시 코드를 읽게 된다면 이 책에서 말한 보다 인간적인 한계들을 좀 더 생각하며 코드를 읽어나가고 싶습니다.

좋은 프로그램이란 무엇인가?

우리는 어떤 프로그램을 다른 프로그램과 비교해 상대적으로 평가하기보다는 개발에 관련된 모든 상황에 비추어 그 프로그램을 평가해야 한다. (51p)

여러분은 이 질문을 듣고 어떤 프로그램을 상상하셨나요? 정확한 프로그램? 빠른 프로그램? 분명 어떤 코드를 보고 한 번쯤, 좋다 나쁘다는 가치 판단을 해보신 적이 있을 것 같습니다. 하지만 그것을 일반화하기는 무척 어려운 일입니다. 저자는 그것이 프로그래밍이 복잡한 인간 행위이기 때문이라고 말합니다. 절대적인 기준을 새우는 것은 고사하고 상대적으로 프로그램 간에 좋고 나쁨을 평가하기도 어렵다고 말합니다. 이는 한 프로그램이 다른 한쪽보다 모든 면에서 우수하기 어렵기 때문입니다. 따라서 우리는 어떤 프로그램이 더 낫다고 말하는 대신, 모든 상황에 비추어 프로그램을 평가할 필요가 있습니다.

저자가 가장 강조하는 것은 요구 명세입니다. 정확성이라고 할 수 있겠습니다. 예상하는 범위의 값을 입력했을 때 잘 작동하여 출력을 내는 것. 이는 회사에서 알고리즘 테스트로 지원자를 평가하고, 그 평가 기준 1번이 “테스트 케이스를 통과할 것”인 이유와 일맥상통하지 않을까 생각합니다. 너무 당연한 얘기일 수도 있지만 100% 정확한 프로그램을 구현한다는 것은 쉬운 일이 아닙니다. 프로그램이 복잡해지고 유저가 많아질수록 예외적인 케이스가 발생할 가능성은 더욱 커집니다. 또한, 프로그램의 목적에 따라서는 6시그마를 달성해야 좋은 프로그램일 수도, 100번 중의 1번 정도는 틀려도 괜찮은 프로그램일 수도 있습니다. 이러다 보면 처음 얘기한 잘 작동한다는 정의도 달라질 수 있겠죠.

다른 평가 기준으로는 일정이 있습니다. 때로는 요구 명세를 모두 만족하는 것보다 일정에 맞게 납품하는 일이 더 중요할 수도 있습니다. 모든 것은 때가 있고, 때를 놓치면 그 가치가 기하급수적으로 낮아지기도 합니다. 이는 프로그램 역시 마찬가지입니다. 그다음으로는 적응성이 있습니다. 한 번만 쓰고 버려지는 코드도 있지만, 대다수의 코드는 일정 기간 생명을 유지하며 유지 보수를 필요로 합니다. 환경이 변화하면서 자연스럽게 새로운 기능을 필요로 하거나, 불필요해진 기능을 삭제할 필요가 있기 때문입니다. 마지막으로는 속도를 뜻하는 효율성이 있습니다. 개인적으로 나날이 늘어가는 컴퓨팅 자원을 고려하면 이제 효율성은 조금 애매해진 게 아닌가 생각하지만, 역시 중요한 평가 기준 중 하나입니다.

제 경우 좋은 프로그램의 정의는 돈을 벌기 시작하면서 끊임없이 고민했던 부분이었습니다. (지금도!) 나만 보고 끝나는 코드가 아니고, 나만 사용하고 끝날 코드가 아닌 이상, 누가 봐도 좋은 코드를 작성하고 싶다는 욕심이 있습니다. 또한, 취미가 아니라 직업으로서 프로그래밍하게 된 이상, 내 의미를 증명하기 위해서라도 가치 있는 프로그램을 만들어야 한다고 생각했습니다. 가치의 정의는 당연히 사람마다 다르겠지만, 적어도 이 책에서 강조하는 형태가 제가 생각하던 것과 일치하는 것이 많아 공감하며 읽을 수 있었습니다.

마치며

1부를 읽으면서, 지금까지 너무 수동적으로 코드를 읽어온 게 아닌가 반성해봅니다. 이 글을 통해 적극적이고 비판적인 프로그램 읽기가 향후 저의 쓰기 실력에도 도움이 될 것이라는 확신을 가지게 됐습니다. 또한 지금까지 저는 생산자로서는 프로그래밍이 인간의 행위라는 것을 이해하고 있었던 것 같지만, 막상 다른 사람의 작업을 받아들일 때는 이런 생각을 덜 해왔던 것 같습니다. 앞으로는 인간 행위라는 점을 의식하면서 프로그래밍을 대해야겠습니다.


Written by@Jaewon Heo
More than yesterday. Less than tomorrow.

InstagramGitHubLinkedIn