코드를 덜 쓰는 일에 대하여

엔지니어로 일한 시간이 길어질수록, 무언가를 지우고 있는 자신을 더 자주 발견한다. 지난달에 쓴 함수, 그때는 영리해 보였던 추상화, 아무도 읽지 않는 설정 파일들.

덜어내는 일에는 조용한 종류의 진전이 있다. 새 기능처럼 커밋 그래프에 드러나지 않고, 체인지로그에 적히는 일도 드물다. 하지만 그 후엔 코드베이스가 조금 더 가볍게 숨을 쉬고, 그 안에서 일하는 사람들도 그렇다.

영리함의 비용

모든 추상화는 미래의 나에게 건네는 약속이다. 그리고 그 약속의 대부분은 지켜지지 않는다. 세 가지 경우를 처리하려던 범용 헬퍼는 결국 한 가지 경우만 어색하게 떠받친다. 두 번째 값을 위해 만들어 둔 유연한 설정은 끝내 그 값을 받지 못한다.

그 약속의 무게는 사라지지 않는다. 다음 사람이 함수 시그니처를 읽고, 분기 하나하나를 따라가고, 왜 이렇게 짜여 있는지 이해하려고 노력하는 동안 계속 쌓인다. 약속을 지키지 못한 추상화는 결국 미래의 누군가에게 청구서를 보낸다.

지루함은 기능이다

올해 내가 내보낸 가장 좋은 코드는 가장 지루한 코드이기도 하다. 평범한 함수, 분명한 이름, '무엇'만으로 '왜'가 보이지 않는 곳에 붙인 몇 줄의 주석. 누구도 그 코드를 칭찬하지 않았다. 그리고 누구도 그 코드에 대해 물을 필요가 없었다.

// before
const result = pipeline(input)
  .map(normalize)
  .filter(predicate)
  .reduce(merge, init);

// after
const normalized = input.map(normalize);
const filtered = normalized.filter(predicate);
const result = filtered.reduce(merge, init);

위쪽이 더 우아해 보인다. 아래쪽이 더 빠르게 디버깅된다. 6개월 후 콘솔에 찍을 변수가 있다는 것의 가치는, 처음 작성할 때는 잘 보이지 않는다.

내일의 나에게 친절할 것

결국 코드는 두 번 읽힌다. 한 번은 컴퓨터가, 한 번은 사람이. 그리고 사람이 읽는 횟수가 압도적으로 많다.

The best code is no code at all.

나는 이 문장을 더 이상 농담으로 듣지 않는다.