나는 짧고 간결한, 요약하는 주석을 강하게 선호한다.

요약하는 주석: 코드 읽기를 도와주는 주석

나는 주석이 복잡한 코드를 요약하는 기능을 가질 때 이상적이라 본다. 그래서 나는 주석에 대해 다음과 같은 규칙을 갖고 있다.

3초 규칙

  • 가독성이 가장 중요하다. 3초 안에 읽고 파악할 수 있어야 좋다.
    • 최소한의 의미만 짧게 담으려 노력한다. 문장이 길어지면 3초 안에 읽지도 못한다.
    • 가장 읽기 쉬운 언어로 적는다. 내가 한국인이고 같이 일하는 사람이 한국인이라면 한국어로 적는다.

책임 또는 의도를 설명한다

  • 함수나 클래스의 "책임"을 짧고 간결하게 적는다.
  • 클래스 시그니처 위에 작성한다면 클래스의 역할에 대해 설명한다.
  • 함수 시그니처 위에 작성한다면 리턴값이 무엇인지 설명한다.

코드와 주석 사이의 커플링을 최소화한다

  • 구현은 가능한 한 설명하지 않는다. 구현을 설명하면 함수 바디와 주석 사이에 커플링이 생긴다.

이런 규칙들의 상세 내역에 대해서는[[/java/javadoc]] 문서에 기록해 두었다.

핵심은 3초 + 요약.

리턴값 위주의 주석은 요약이라는 목표를 위한 지침일 뿐이다.

스티브 맥코넬은 Code Complete 2에서 이렇게 말했다.

코드를 요약하는 주석은 그저 요약을 할 뿐이다. 이러한 주석은 몇 줄의 코드를 한두 개의 문장으로 나타낸다. 그러한 주석들은 단순히 코드를 반복하는 주석보다는 훨씬 가치가 있다. 왜냐하면 코드를 읽는 사람이 코드를 보다 빠르게 살펴볼 수 있기 때문이다. 요약 주석은 코드를 작성한 사람보다는 다른 사람이 해당 코드를 수정하려고 할 때 특히 유용하다. 1

brain dump: 정신 모델을 백업하는 주석

필요하다면 작업 중일 때의 머릿속 상태를 빨리 복원하기 위한 주석을 작성할 수도 있다.

코드만으로 문제를 충분히 표현할 수 없는 경우에는 이런 brain dump를 위한 주석을 진지하게 고려할 수 있어야 한다.

일부 개발자들은 주석문을 광범위하게 사용하는 것을 바람직하지 않은 것으로 생각하는데, 그 이유는 코드가 '그 자체로 문서'이어야 하고, 따라서 주석문은 불필요하다는 것이다. 그러나 코드는 프로그래머의 사고 과정을 거의 설명하지 못하므로 대부분 작성자의 정신 모델을 적절하게 표현하지 못한다. 우리는 코드에 특정 접근 방식을 선택한 이유, 코드의 목표 또는 구현을 위해 고려한 다른 대안 같은 내용을 코드에 기록해놓는 것에 익숙하지 않다. 이런 종류의 내용이 어디에도 기록되지 않는다면, 기껏해야 암묵적으로 발견될 수밖에 없는데, 이것은 분명히 시간이 오래 걸리는 과정이다. 존 오스터하우트John Osterhout는 《A Philosophy of Software Design(소프트웨어 설계의 철학》 (Yaknyam Press, 2018)에서 이것을 멋지게 묘사했다. "주석문의 배후에 놓인 전반적인 아이디어는, 설계자의 마음속에는 있었지만 코드로 표현할 수 없었던 정보를 포착하는 것이다."

어떤 결정을 내렸는지 문서화해놓으면 다른 사람이 코드를 읽을 때 매우 유용할 뿐만 아니라 자기 자신의 정신 모델을 일시적으로 저장하는 데도 도움이 되고 나중에 작업을 쉽게 재개할 수 있다. 프레더릭 브룩스Frederick Brooks는 《맨먼스 미신》(인사이트, 2015)에서, 주석문은 항상 존재하기 때문에 프로그램 이해 과정에서 가장 중요하다고 말한다. 종이 또는 문서에 적어놓은 노트가 유용하지만 코딩 작업을 다시 시작할 때 관련 문서를 찾는 것은 정신적인 노트를 추가하는 것이 될 수 있다.

업무가 중단될 상황에서 잠시 시간 여유가 있다면, 예를 들면 슬랙 메시지나 동료가 옆에서 잠시 기다려도 되는 상황이라면, 코드에 대한 최신 정신 모델을 주석문의 형태로 '브레인 덤프brain dump' 하는 것이 아주 유용할 수 있다. 항상은 아니더라도, 경우에 따라서는 도움이 될 수 있다. 2

sub goal: 의사 코드, 구현 목표로서의 주석

나는 먼저 구현에 대한 메모 또는 의사 코드로서 주석을 작성해놓는 방법도 좋아한다. 단, 이렇게 작성한 주석 대부분은 구현이 완료된 시점에 삭제하여 완성된 코드에게 자리를 내주는 것이 좋다고 본다.

아래는 2021년 9월 28일 화요일에 나에게 코딩 테스트에 대해 조언을 요청한 분께 보낸 답장 이메일의 일부이다.

  1. 코딩테스트 플랫폼에 처음부터 코딩을 하지 않습니다. 처음엔 주석을 씁니다. 주석으로 내가 문제를 파악한 내용과, 문제를 풀 계획, 감정 등을 주석으로 줄줄이 써내려갑니다.
  2. 주석을 읽으면서 조금씩 주석 아래에 코드를 작성해 나갑니다.
  3. 간단한 테스트 케이스가 생각날 때마다 주석에 추가로 작성해 봅니다. (처음에 쓴 주석을 아직 지우면 안됩니다.)
  4. 풀다가 잘 안 풀리면 그것에 대한 고민도 주석으로 씁니다. 친구랑 채팅한다고 생각하세요. 그리고 스스로 답변도 쓰세요. ( // 이 부분을 모르겠다. // 왜 모를까? // 이 변수의 값이 null이 되면 어떤 일이 일어날까? // 13번 라인에서 NPE가 발생할거야. NPE를 방지해야겠다. )
  5. 이렇게 문제를 풀어나갑니다.
  6. 문제를 다 풀면 감정과 관련된 주석, 불필요한 주석을 모두 지웁니다. 하지만 테스트 케이스나 핵심 아이디어에 대한 주석은 삭제하지 않습니다.
  7. 제출합니다.

이 방법을 쓰면 주석을 쓰면서 자신의 생각을 정돈할 수 있고, 코딩을 하면서 내가 어느 단계에 와 있는지를 눈으로 확인할 수 있다. 그래서 나는 이 방법을 종종 사용한다.

이런 주석은 구현이 완료된 시점에서는 코드와 커플링이 생기므로 삭제하는 것이 좋은 선택일 경우가 많다.

"프로그래머의 뇌"에서는 이 방법에 대해 "하위 목표subgoal"라는 단어로 표현한다.

필자가 만일 이 예제와 같은 작업을 프로그래밍한다면 다음과 같이 각 단게를 주석문으로 써놓고 시작할 것이다.

# 텍스트 구문 분석
# 구문 분석 트리 생성
# 구문 분석 트리 필터링
# 트리를 선형 구조로 변환해 텍스트 만들기

이렇게 하면 코드의 작은 부분을 채울 수 있고, 실패 시 대처할 계획을 항상 가질 수 있다. 조지아 주립 대학교 학습과학과의 로런 마굴리외Lauren Margulieux 교수가 프로그래머를 대상으로 수행한 한 연구에서, 하위 목표가 제공될 때 프로그래머들이 그것을 사용해서 머릿속에서 해결책을 조성한다는 것이 밝혀졌다.

하위 목표는 업무가 중단된 후에 하던 업무를 계속할 때 자신의 생각을 정리하는 데 유용하지만, 다른 상황에서도 유용하다. 예를 들어 코드에 있던 하위 목표 중 일부는 주석으로 남아 나중에 설명서의 역할을 할 수 있다. 또한 수석 프로그래머가 하위 목표를 설계하고 다른 프로그래머가 더 큰 해결책의 일부를 구현하는 협업에도 사용할 수 있다. 3

주의: 코드와 주석의 괴리

If the code and the comments disagree, then both are probably wrong.
Norm Schryer
Bell Labs

코드와 주석이 일치하지 않는다면 둘 다 틀렸을 가능성이 크다.
– 슈라이어Norm Schryer 4

문제는 코드와 주석 사이에 괴리가 생기는 경우이다. 만약 주석은 명확한데 구현에 버그가 있거나, 주석과 다른 내용이 구현되어 있다면 주석이 없는 것이 나을 수 있다.

이는 위에서 이야기한 코드와 주석의 커플링에서 발생하는 문제이기도 하다.

제랄드 와인버그는 "프로그래밍 심리학"에서 다음과 같이 말한다.

코드에 주석을 다는 목적은 읽는 이가 코드를 직접 보기 전에 적당한 마음의 준비를 하게 만들려는 것이다. 그 코드가 정확히 구현되어 있다면, 주석문은 확실히 효과가 있다. 그러나 코드가 부정확하다면, 읽는 사람의 심리적 자세가 주석문의 지배를 당하기 때문에 오류를 찾아내는 데 오히려 방해가 된다.

주석문만 다른 동일한 코드의 여러 버전을 가지고 실험하면, 잘못된 코드를 해석하는 데 있어 주석문이 미치는 영향을 알 수 있다. 즉, 한 버전에는 정확한 주석문을, 다른 버전에는 부정확한 주석문을 넣고, 또 다른 버전에는 주석문을 아예 넣지 않는 것이다(Okimoto, 1970). 어떤 종류의 코드는 주석문이 없어도 그 역할을 금방 명확하게 알 수 있다. 그리고 주석문이 정확하면 부정확하거나 오해를 부를 만한 주석문이 포함되어 있는 경우에 비해 코드를 해석하기가 더 쉽다. 그러나 많은 프로그래머가 오류를 찾기 위해 코드를 파헤칠 때 포함되어 있는 모든 주석문을 읽으려는 습관을 갖고 있다. 주석문은 오류가 없는 코드를 이해할 때에는 도움이 되지만, 디버깅을 할 때에는 심리적 자세를 교란시켜 오히려 독이 된다. 5

함께 읽기

  • [[/java/javadoc]]

참고문헌

  • C++로 배우는 프로그래밍의 원리와 실제 / Bjarne Stroustrup 저 / 류광 역 / 대웅출판사 / 발행일 2010년 08월 01일 초판 1쇄 / 원제: Programming: Principles and Practice Using C++, 1st Edition
  • CODE COMPLETE [2판] / Steve McConnell 저 / 서우석 역 / 정보문화사 / 2005년 04월 22일 초판 발행
  • 프로그래머의 뇌 / 펠리너 헤르만스 저/차건회 역 / 제이펍 / 2022년 01월 12일 / 원제 : The Programmer's Brain
  • 프로그래밍 심리학 / 제럴드 M. 와인버그 저 / 인사이트(insight) / 신판 1쇄 발행 2014년 01월 02일

주석

  1. CODE COMPLETE. Chapter 32. 1076쪽. 

  2. 프로그래머의 뇌. 11장. 199쪽. 

  3. 프로그래머의 뇌. 11장. 202쪽. 

  4. 이 인용구는 John Bently의 "More Programming Perls" 6장에서 인용한 것을 옮겨온 것이다. 내가 알기로 아직까지(2023-03-25) 이 책은 한국어로 번역되지 않았다. 한편, 아래의 한국어 번역은 "C++로 배우는 프로그래밍의 원리와 실제" 부록 D 표지의 문구를 옮긴 것이다. 

  5. 프로그래밍 심리학. 9장. 303쪽.