2P by GN⁺ | ★ favorite | 댓글 1개
  • 2년간 직접 쓰며 고쳐 온 프로그램의 핵심을 한 달 동안 다시 작성한 경험이, 테스트와 버전 관리에 대한 기존 믿음을 흔들었음
  • 2015년에는 나쁜 추상화보다 테스트와 버전이 오래 가는 소프트웨어의 핵심이라고 봤지만, Mu와 Freewheeling Apps를 거치며 실제 작업 방식은 점점 달라짐
  • 오래 지속되는 프로그램은 많은 사람을 대상으로 하기보다, 잘 아는 사람·맥락·기능 안에서 만들고 Dunbar's number 같은 현실적 한계를 받아들여야 한다고 봄
  • 타입, 추상화, 테스트, 버전, 상태 기계, 불변성, 형식 분석은 낯선 영역에서 유용하지만, 과하면 불필요한 복잡성을 가리는 기술 부채가 됨
  • 맥락 이해가 안정되면 큰 부분을 버리고 다시 만들 가치가 있으며, 필요한 시나리오를 한꺼번에 머릿속에 올린 뒤 전체를 한 번에 구성해야 함

테스트와 버전 관리에 대한 생각의 변화

  • 오래 의존할 수 있는 프로그램을 고르고 직접 만드는 문제를 계속 다뤄 왔지만, 스스로도 그 일을 잘한다고 느끼지는 않음
  • 최근 한 달 동안 2년간 사용하고 점진적으로 수정해 온 프로그램의 핵심을 재작성
    • 이후 며칠 동안 무엇을 배웠고 다음에 어디로 갈지 정리하는 시간이 이어짐
    • 이번 작업을 계기로 더 넓은 생애적 변화가 보이기 시작함
  • 2015년에는 추상화를 의심하고 테스트와 버전 관리를 중시함
    • 코드에는 나쁜 추상화가 많고, 테스트와 버전은 2000년대의 핵심 진전이라고 봄
    • 문제의 원인을 나쁜 인센티브, 과도한 추상화, 부족한 테스트와 버전에서 찾음
    • Mu1은 테스트와 layers를 기반 제약으로 삼는 플랫폼 설계 시도였음
  • 2017년에는 Mu1을 현재의 Mu로 다시 작업하기 시작함
    • 초기에는 테스트와 레이어에 관한 새 아이디어를 모두 사용함
    • 시간이 지나며 그 아이디어들을 덜 쓰게 됨
    • 현재 Mu에는 테스트가 많지만 대부분 일반적인 테스트이고, 레이어 인프라는 옮기지 못함
  • 2022년에는 Freewheeling Apps를 만들기 시작함
    • 처음에는 테스트가 없었고, 나중에 핵심 조각인 텍스트 편집기에 대해 철저한 테스트를 작성함
    • 나머지를 테스트하는 방법은 찾기 어려웠지만, 테스트 없이도 충분히 진행됨
  • 2024년에는 모든 테스트를 삭제함
    • 텍스트 편집기를 크게 다시 만들기 시작했고, 이 방식은 다른 Freewheeling Apps와의 병합 충돌을 걱정하게 만들 수 있었음
    • 결과적으로 버전 관리에 대한 생각도 멈춤
    • 테스트와 버전을 포기한 뒤 더 나은 프로그램을 얻으면서 기존 믿음과의 인지 부조화를 더는 무시하기 어려워짐

오래 지속되는 프로그램을 위한 현재의 정리

  • 많은 사람을 위해 오래 가는 것을 만드는 일은 너무 어렵기 때문에, 처음부터 그렇게 시도하지 않는 편이 낫다고 봄
    • 잘 아는 것, 잘 아는 사람, Dunbar's number에 지배받아야 함
  • 세상 대부분의 소프트웨어는 단기적으로 많은 사람을 섬기려는 인센티브에 감염돼 있다고 봄
    • 가능한 한 웹사이트에 로고가 많지 않은 소프트웨어에 집중함
    • 만들기 쉽고, 의존성이 적고, 자동 업데이트를 하지 않는 소프트웨어를 선호함
    • 이런 제한으로 걸러 보면 인류가 지금까지 만든 오래 가는 소프트웨어의 양은 매우 작음
  • 사람, 장소, 지원하려는 기능 같은 맥락의 작은 변화도 프로그램이 그 맥락에 얼마나 잘 맞는지를 크게 바꿀 수 있음
    • 단기주의가 지배적인 환경에서는 이 사실에 대비하기 어려움
  • 과거 작업의 양이 작고 프로그램별 적용 범위도 낮기 때문에, 새로 만들기로 한 프로그램은 어떤 식으로든 미지의 영역에 들어갈 가능성이 큼
    • 텍스트 편집기에 특수한 “drawing lines”를 넣으려 할 때도 여러 질문이 생김
      • 커서가 그림 위에 있을 수 있는가
      • 커서가 다른 줄에 있을 때 한 줄에 그림을 그릴 수 있는가
      • 그림은 텍스트 줄보다 높은데, 화면 위쪽에서 부분적으로만 보일 수 있는가
      • 부분적으로 보이는 그림 위에 그릴 수 있는가
    • 이 질문들에 대한 답이 오랫동안 최적이 아니어서, 임시방편 위에 또 임시방편이 쌓임

도구는 필요하지만 과하면 기술 부채가 됨

  • 타입, 추상화, 테스트, 버전, 상태 기계, 불변성, 형식 분석은 낯선 지형에서 사용할 수 있는 도구
    • 필요한 만큼 취향에 맞게 쓰면 됨
  • 사람은 자신이 끌리는 도구를 과하게 쓰기 쉬움
    • 이 도구들의 이상적인 사용량은 매우 작다고 봄
    • 단기주의가 지배적인 환경에서 배운 감각보다 훨씬 더 작아야 함
  • 도구를 초과 사용하면 기술 부채가 됨
    • 프로그램이 불필요하게 복잡하다는 사실을 알아차리기 어려워짐
    • 프로그램이 더 오래 갈 수 있는 상태보다 덜 오래 가게 됨
    • 맥락이 바뀔 때 프로그램을 더 바꾸기 힘들어짐

다시 쓰기와 “한 번에 전체 만들기”

  • 맥락에 대한 이해가 안정되면 프로그램의 큰 부분을 버리고 처음부터 다시 하는 데 가치가 있음
  • 다시 쓰기 전에는 프로그램에서 원하는 모든 것과 대응해야 할 모든 시나리오를 한꺼번에 머릿속으로 가져와야 함
    • 이 과정은 어렵지만, 목표는 모든 것을 한 번에 만들 수 있는 상태에 도달하는 것임
  • 최종 방식은 모든 것을 한 번에 만드는 것
  • 이번 경험에서는 테스트와 버전이 이 진화의 끝에 도달하는 데 오히려 방해가 됨
    • 테스트는 걱정해야 할 문제를 잊게 함
    • 버전 관리는 과거에 계속 붙잡히게 함
    • 둘 다 역효과였고, 이를 내려놓으려면 큰 방향 전환이 필요했음
  • 지금까지 만든 모든 소프트웨어와 Freewheeling Apps는 이 궤적의 6단계에 있다고 봄

복잡성의 한계와 데이터 지향 설계

  • 프로그램이 너무 복잡해지면 8단계에서 머릿속에 통째로 올리는 것이 불가능해질 수 있음
    • 지금까지의 대부분 소프트웨어, 특히 두어 명보다 많은 사람이 작성한 소프트웨어가 여기에 해당한다고 봄
    • 작은 텍스트 편집기조차도 부담스러워서, 한 달 중 많은 시간을 그 두려움에 맞설 준비에 썼음
  • 모든 소프트웨어가 반드시 9단계까지 갈 필요는 없음
    • 많은 Freewheeling Apps는 충분히 단순하고 천천히 진화함
    • 소수의 사람이 사용하는 것만으로도 초기 설계 선택과 무관하게 버그 없는 상태로 안정화될 수 있다고 봄
    • 특히 이제 핵심의 복잡한 조각 하나를 간소화하는 방법을 알게 됨
  • 그래도 가치가 생기면 어떻게 개선할 수 있는지 아는 것이 좋음
  • 9단계에 도달하는 데 확실히 유용해 보이는 방법으로 data-oriented design을 꼽음
    • 맹목적으로 적용할 수 있는 도구가 아니라, 프로그램이 데이터를 어떻게 접근하는지 큰 그림으로 보는 사고방식임
    • ECS 같은 도구가 본질적인 지적 활동을 가리지 않게 해야 함
  • 이 단계 구분은 완전히 맞지 않을 수 있음
    • 경험이 적은 도구들을 과소평가하고 있을 수 있음
    • 이 단계 너머에 무엇이 있는지도 아직 열린 질문으로 남아 있음
  • 2019년에 쓴 프로그래밍 방식에 대한 글 이후 생각이 변한 흔적을 볼 수 있음

댓글과 토론

Hacker News 의견들
  • 테스트가 없으면 테스트 실패가 보이지 않으니 문제가 사라진 것처럼 보일 뿐임
    뭔가를 테스트했는데 버그를 못 찾은 적이 없고, 테스트한 대부분은 이미 출시해도 된다고 생각했던 것들이었음
    테스트를 지우면 결국 속이는 사람은 자신뿐일 가능성이 큼. 글을 읽어보면 테스트 자체보다 변형/설정 관리에 지친 것처럼 보이고, 그건 충분히 공감됨. 다만 사용자 수가 있어야 돈이 되고, 쉬운 문제였다면 이미 만능 솔루션으로 시장이 포화됐을 것임

    • 이건 도메인 의존적이라고 봄. 지금 작업 중인 코드베이스의 어떤 부분은 테스트가 리팩터링에 큰 도움이 되지만, 다른 부분은 UI 동작이 많아서 수동 테스트가 훨씬 빠름
      UI나 워크플로가 너무 빨리 바뀌면 다음 반복에서 쓸모없어질 걸 알기에 테스트를 안 쓰게 되고, 반대로 너무 느리게 바뀌면 그 부분은 다시 건드릴 일이 없어 리팩터링으로 새 버그가 들어갈 일도 적음. 테스트나 타입은 만능 성배가 아니라 작업에 맞는 도구임. 좋은 테스트 커버리지가 있어도 수동 테스트나 실제 사용으로 버그가 발견되지 않는 코드베이스는 본 적이 없음. 약간 과장해서 말하면, 완벽한 테스트를 쓸 수 있을 만큼 뛰어나다면 그냥 완벽한 코드를 쓰면 됨. 테스트를 완벽하게 못 쓴다면 그 테스트가 완전하고, 버그 없고, 실제로 유용하다는 걸 어떻게 아는가 싶음
    • “테스트는 버그의 존재는 보여줄 수 있지만, 부재는 보여줄 수 없다”는 말이 내 경험에는 더 잘 맞음
      몇 달마다 새 버그를 찾고 성실히 테스트를 추가했지만, 몇 달 뒤 처음 10분 써본 사람이 또 새 버그를 발견하곤 했음. 새 버전에도 발견할 버그는 있겠지만, 선택한 자료구조 덕분에 예전 테스트 상당수는 구조적으로 필요 없어졌다고 봄. 적어도 가벼운 사용에는 몇 개의 버그만 더 잡으면 꽤 안정적일 거라 기대함. 테스트는 큰 팀이 코드베이스를 계속 바꿀 때 매우 소중하지만, 여기서는 고정된 기능 집합을 가진 무언가를 만들려는 중임
    • 최근 스레드에서 추천된 Russ Cox의 Go Testing By Example 영상을 봤음: https://www.youtube.com/watch?v=X4rxi9jStLo
      유용한 조언이 아주 많지만, 특히 언급하고 싶은 건 더 단순한 구현, 예컨대 무차별 대입 구현을 기준으로 테스트할 수 있다는 점임. 여기에는 더 깊은 지혜가 있음. 테스트의 유용성은 테스트 구현이 테스트 대상 구현보다 얼마나 단순한지에 달려 있음. 더 강하게 말하면, 테스트는 테스트 대상보다 단순할 때만 유용함. 아무리 테스트를 많이 써도 결국 코드를 추론해야 하고, 무언가가 “테스트”라는 사실만으로 유용해지는 건 아님. 그래서 많은 프로그래머가 테스트를 쉽게 쓰려고 유용한 인터페이스가 아닌 조각으로 함수를 쪼개거나, 커버리지만을 위해 단순한 헬퍼나 작은 질의를 테스트하거나, 테스트만을 위해 추상화를 도입하는 의존성 역전과 모킹을 경계한다고 봄. 물론 각각에 이유가 있을 수 있지만, 핵심을 잃지 않는 게 중요함
    • 내 경우 단위 테스트를 쓸 때마다 버그가 드러났음
      보통 실패하는 테스트를 먼저 쓰는 테스트 주도 개발 방식은 잘 안 하지만 가끔은 함. 그래서 이런 테스트는 대개 이미 동작한다고 생각한 코드를 대상으로 함. 다만 보통은 단위 테스트보다 테스트 하네스를 선호함[0]. 여전히 버그를 찾지만 흐름은 덜 직선적임. 개발 중 더 많이 테스트하게 만들어서 버그를 그 자리에서 고치게 해줌
      [0] https://littlegreenviper.com/testing-harness-vs-unit/
    • 자동화된 단위/통합 테스트에 집중하는 건 비교적 현대적인 흐름이고, 아마 90년대 후반쯤부터일 것임. 그 전에도 꽤 크고 매우 안정적인 소프트웨어가 출시됐음
      예를 들어 Linux 커널은 예전엔 테스트가 많지 않았고, 요즘은 더 많아진 듯함. Unix도 “테스트”가 많진 않았을 것임. 컴파일러는 테스트가 있는 편이었지만 운영체제는 덜했고, Doom 같은 게임도 테스트가 많지 않았을 가능성이 큼. 결국 균형점을 찾아야 함. 자동화 테스트, 즉 단위·통합·종단 테스트가 품질 좋은 소프트웨어를 만드는 데 도움이 된다는 건 알고 있음. 동시에 좋은 테스트는 늘 쓰기 쉽지 않고, 나쁜 테스트는 리팩터링을 어렵게 만들며, 불안정한 테스트는 큰 프로젝트에서 많은 시간을 잡아먹음. 그래도 특히 혼자 개발한다면 여러 방식을 시도해 보고 자신에게 맞는 걸 찾는 건 흥미로운 일임
  • “테스트와 버전을 포기하자 훨씬 나은 프로그램이 됐다”는 부분은 이해하기 어려움. 2024년에 누가 자발적으로 소스 코드 관리 없이 프로그래밍하려는지 모르겠음
    1인 프로젝트라도 여러 기기에서 작업하고, 이력을 보고, 되돌리고, 브랜치를 쓰는 능력은 거의 비용 없이 매우 큰 가치를 줌. 아마 저자가 “버전”으로 뜻한 걸 내가 오해한 걸 수도 있음

    • 작고 빠르게 기능 집합이 고정되는 무언가를 만들려는 중임. 자주 바뀌지 않는 기반 위에 만들기로 했고, 배경은 https://akkartik.name/freewheeling에 더 있음
      이 접근이 오늘날 사람들이 만드는 대부분의 프로그램, 즉 큰 팀과 계속 변하는 요구사항에는 맞지 않는다는 말은 맞음. 그래도 소스 관리는 여전히 사용함. 원문에서 말했듯 다른 포크와 병합 충돌을 일으키는 걱정을 그만뒀을 뿐임. 지금은 포크가 24개가 넘고, 자세한 내용은 위 링크에 있음. 백업, “방금 뭘 바꿨지?”, 새 기기에 소프트웨어를 올리는 같은 기본 용도에는 버전 관리를 씀. 다만 이 프로그램에 한해서는 버전 관리를 무엇이 바뀌었는지 이해하고 추적하는 수단으로 생각하지 않게 됐음. 자세한 내용은 https://akkartik.name/post/wart-layers에 있음. 예를 들면 커밋 메시지 위생에 덜 신경 쓰게 됨. 버전 관리는 존재하지만, 기능 집합이 고정되고 수십 년 지속될 내구성 있는 산출물로 만들려는 이런 좁은 맥락에서는 “좋은 프로그래밍 관행”으로서 우선순위가 낮아졌음
    • 저자는 전문 사용자나 유료 사용자를 지원해야 하는 상황이 아닌 듯하고, 알려진 정상 버전을 보장하는 것보다 실험의 자유를 더 원하는 것처럼 보임
      큰 시스템을 다루거나 중요한 팀 작업을 하는 상황도 아닌 듯함. 이런 조건에서는 도구들이 큰 가치를 주지 않을 수 있음. 복잡한 교향곡을 연주하는 대형 오케스트라의 플루트 연주자는 악보와 지휘자가 필요하지만, 드럼 머신에 맞춰 혼자 연주하거나 자유 재즈를 한다면 악보가 별로 필요 없고 오히려 방해될 수도 있음
    • 저자는 프로그래밍에 대한 정신적 피로나 번아웃을 겪는 것 같음. 버전 관리가 그 정도로 거슬린다면 쉬어야 한다는 꽤 좋은 신호라고 봄
    • 프로그래머는 선택지와 옵션에 계속 압도됨. 도구와 시대정신이 말하는 “최고의 도구”는 대체로 어떤 일을 더 쉽게 만드는 방향으로 흐름
      하지만 쉬운 선택지 1000개가 항상 있으면 올바른 선택을 고르는 데 큰 인지 부담이 생김. 업계가 온갖 모범 관행을 신성시하고 따르지 않는 사람을 사회적으로 압박하는 이유 중 하나도 그 때문임. 나쁜 아키텍처와 끔찍한 스파게티 코드는 일하기 매우 힘들지만, 당연히 옳아 보이는 것들을 의심하고 선택지와 도구를 줄이는 엄격한 개발 환경을 탐색하면 최종 문제에 더 집중할 수 있음. 버전 관리도 브랜치가 프로그램을 “독립 기능”으로 쪼개도록 유도하고, 이력은 낡았을 수 있는 기능 단위를 맹목적으로 쓰게 만들며, 협업은 보통 무관한 조직 경계를 코드 아키텍처에 굳혀 넣음. Mel Conway가 말한 것과도 닿아 있음. 버전 관리의 이점은 상식이지만, “비즈니스 문제 X를 해결한다”는 수준에서는 실제 절충이 존재함. 업계 차원에서 이런 절충이 거의 보이지 않는다는 게 시사적임
    • 이 경우 저자가 말한 건 앱 자체에 버전 로직을 코딩하는 걸 뜻하는 듯함. 예를 들면 하위 호환성을 위한 버전별 API 엔드포인트 같은 것임
  • 처음엔 저자가 완전히 틀렸다고 생각했지만, 그래도 좋은 통찰이 좀 있음
    이 작업 흐름은 저자에게는 아주 잘 맞음. 우리 대부분도 Git이나 자동화 테스트 때문에 좌절하거나 생산성이 떨어졌던 때를 떠올릴 수 있음. Dropbox, FTP 등으로 코드를 백업하는 식의 더 단순하고 방해되지 않는 해법도 있음. 위 방식이 잘 맞는 이유는 저자가 소수와 협업하는 개인 애정 프로젝트에서 자신의 생산성을 최적화하고 있기 때문임. 자동화 테스트는 유용하지만, 저자는 그 가치가 드러나기 어려울 만큼 작은 프로그램을 만드는 걸 좋아하는 듯함. 이 맥락에서도 자동화 테스트의 가치는 있다고 보지만, 자동화 테스트가 속도를 늦춘다는 데는 모두 동의할 수 있음. 물론 많은 사람은 나중에 보상이 돌아온다고 주장할 것임. 버전 관리와 자동화 테스트는 실제 문제를 해결함. 오늘날 버전 관리 없이 프로젝트를 시작하는 건 말이 안 되고, 자동화 테스트가 모범 관행인 데는 이유가 있음. 다만 저자의 특정 사용 사례에서는 합리적으로 들림. 논란 많은 버전 관리/테스트 부분을 빼면, 항목 7/8/9는 큰 프로그램을 작성하고 리팩터링할 때 내 사고방식을 완벽히 포착함. 쓰고, 버리고, 다시 씀

    • 버전 관리에는 동의하지 않음. 혼자 하는 프로젝트이고 여러 버전 브랜치가 없어도 마찬가지임
      사람은 실수하고, 10만 줄 넘는 프로젝트에서 지난 3주 동안 무엇을 바꿨는지 아는 건 큰 도움이 됨. 문제를 찾고 고치는 데 유용함. 더 좋은 기능은 브랜치로, 이전 안정 상태로 돌아갈 방법을 유지한 채 원하는 걸 해볼 수 있게 해줌. 자동화 테스트는 없어도 괜찮다고 봄
    • 혼자 프로젝트라도 .gitignore를 설정하고 git init, git add -A, git commit -a -m "before I changed the foo function to use bar" 정도를 실행해 이전 리비전으로 돌아갈 수 있을 만큼 Git을 배우는 시간은 충분히 가치 있음
      Git을 마스터할 필요는 없지만, 커밋 메시지와 돌아갈 버전이 있는 것만으로도 셀 수 없이 많이 구원받았음. 더 고급 기능은 말할 것도 없음
  • 혼란스러운 글임. 무엇 때문에 1위까지 올라갔는지 정말 궁금함

    • 한쪽으로는 자신의 삶을 발전시키려고 다른 도구와 기법을 실험하는 개발자의 글일 수 있음. 다른 한쪽으로는 사람들을 논쟁으로 몰아넣으려는 낚시일 수도 있음
  • 합리적인 테스트 묶음을 갖추는 주된 동기는 좌절을 줄이는 것임. 테스트 묶음은 개발자가 시스템을 진화시킬 자신감을 줌
    제대로 만들면 “나머지를 테스트할 방법을 찾기 어려웠고, 어쨌든 괜찮게 해나갔다”와 비슷한 생각도 자주 생김. 기능 복잡도가 커질수록 컴포넌트나 시스템 전체를 테스트하는 난이도가 감당하기 어려워질 수 있음. 하지만 테스트와 버전 관리를 포기해 더 나은 프로그램이 됐다는 철학은 한 사람을 넘어서 확장되지 않음. 그것도 그 사람이 소스 코드에 담긴 현재와 과거의 모든 결정을 최근의 친밀한 기억으로 알고 있을 때만 가능함. 게다가 구현을 깊이 알고 있다면 모든 변경 검증은 정의상 수동으로 수행해야 함

    • 예전에 HN에서, 그날 직접 쓴 코드가 아니면 절대 병합하지 않는 사람의 이야기를 본 적이 있음
      하루가 끝날 때 병합 가능한 상태가 안 됐다면, 그건 하루 안에 표현할 만큼 문제를 충분히 이해하지 못했다는 뜻이라 다음 날 아침 새로 시도했다는 내용이었음. 이걸 기억하는 사람이 있는지, 아니면 다른 사이트나 일화를 헷갈리는 건지 모르겠음
    • 1인 프로그래밍 팀으로서는 맞는 말임. 솔직히 혼자 일하더라도 테스트 묶음이나 버전 관리 없이 프로그래밍하는 건 생각만 해도 겁남
      문서, 테스트, 버전 관리는 코드 맥락에 대해 내가 기억해야 할 양을 줄여줌. 눈앞의 코드 세부사항은 기억해야 하지만, 문서화하고 테스트하고 왜/어떻게 바꿨는지 좋은 커밋 메시지와 함께 체크인하면 그 코드를 머릿속에서 비우고 다음 일로 넘어갈 수 있음
  • “지원하려는 사람/장소/기능 같은 맥락의 작은 변화가 프로그램이 그 맥락에 얼마나 잘 맞는지를 급격히 바꾼다”는 3번 항목의 좋은 예는 K9 Mail임. 이제 Android판 Thunderbird가 되어가는 중임
    K9 Mail은 이메일 계정 목록을 홈 화면에 보여주고 각 계정의 안 읽은 메시지 수와 전체 메시지 수를 표시하는 비전통적 UI로 시작했음. 통합 받은편지함은 있었지만 사용자에게 강요하지 않았음. 개인 계정 하나, 업무 계정 하나, 고객들이 준 여러 업무 계정을 분리해 두고 싶어서 이 앱을 명시적으로 선택했던 기억이 있음. 아마 많은 K9 사용자도 같은 이유로 이 앱을 골랐을 것임. 개발자가 왼쪽에서 계정 목록이 슬라이드되고 계정 간 이동에 탭이 하나 더 필요한 전통적 Android UI로 옮겼을 때 불만이 많았던 이유도 그 때문임. 우리가 그런 UI를 좋아했다면 애초에 K9을 고르지 않았을 가능성이 큼. 그래서 작은 변화 하나, 하지만 코딩은 많았을 변화가 사용자에게 맞던 앱의 적합성을 망쳤음. 나는 옛 UI가 있는 마지막 버전인 5.600을 계속 쓰고, 새 기기를 살 때마다 사이드로드함. 더 특이하게도 계정 접근에는 POP3만 씀. 휴대폰에서 미리 보고, 지울 건 지우고, 필요하면 내게 숨은참조로 답장한 뒤 결국 노트북에서 내려받는 흐름인데 K9이 이 워크플로에 완벽히 맞았음. 화려한 건 필요 없고, 90년대 앱 정도면 충분함

  • 이 길이 어디로 이어질지 나도 계속 궁금함. 한 가지는 분명한데, 혼자 소프트웨어를 만드는 일은 팀에서 만드는 일과 완전히 다른 활동임
    테스트에 관해서는, 테스트는 목적이 아니라 수단임. 우리가 찾는 건 자신감이라고 생각함. 구현에 자신이 있으면 테스트를 덜 함. 반대로 반드시 계속 동작해야 하는 게 있으면 리팩터링의 영향을 덜 받아 속도를 덜 늦추는 바깥 경계에 통합 테스트를 몇 개 추가함. 내부를 테스트하기보다 웹 백엔드를 바깥에서 찔러보는 식임. 단위 테스트는 새 API 설계를 구체화하는 데 좋지만, 방향을 알게 된 뒤에는 그 테스트들이 거의 쓸모없어짐

    • 1인 프로젝트에도 테스트를 둘 좋은 이유는 정말 많음
      만들고 있는 기능으로 바로 가려고 true || 같은 식으로 if 문을 임시 고정하는 건 시간이 들고 나중에 제거해야 함. 그냥 테스트를 만들고 실행하면 회귀 테스트로 남길 수 있음. 큰 앱이나 느린 앱을 배포한다면, 때로는 Qt를 쓴다는 것만으로도 빌드나 실행이 오래 걸리는데, 그럴 땐 단일 테스트가 더 빨리 로드되고 더 빨리 실행됨. 버그 재현에 45초가 걸린다면 테스트를 쓰는 편이 낫음. 일의 가장 지루한 부분을 자동화하고, 흐름을 유지하며, 확인할 가치가 있는지 매번 생각하지 않아도 원하는 만큼 자주 버그 상태를 확인할 수 있고, 역시 회귀 테스트로 남길 수 있음
  • 이 저자를 정말 좋아하고, Mu는 내가 가장 좋아하는 프로젝트 중 하나임. 현대적인 Lisp 머신 비슷한 것, 그것도 QEMU에서 돌아가는 재미있는 프로젝트임

  • “대부분의 소프트웨어는 단기적으로 많은 사람을 섬기려는 인센티브에 고칠 수 없을 만큼 감염돼 있다”는 문장이 좋음. 소프트웨어를 “비즈니스”로 바꿔도 그대로 통함

  • 우리는 모두 소프트웨어 공학 분야의 복잡성에 어느 정도 압도돼 있음. 때로는 그 복잡성이 우발적이기도 함
    하지만 수십 년 동안 만들어낸 모든 아이디어를 거부하는 게 해결책이라는 데는 동의하지 않음. 반대로 모든 해법을 글자 그대로 받아들이거나 “너무 많이” 쓰면 안 됨. 압도된다는 건 정의상 무언가를 너무 많이 쓸 때 생김. 테스트를 쓰고, 버전 관리 시스템을 쓰고, 추상화를 쓰되, 왜 쓰는지 알아야 함. 그 “왜”가 더 이상 성립하지 않으면 다시 평가해야 함

    • 문제의 큰 원천 중 하나는 학계라고 봄. 덴마크에서 CS 학생들의 외부 시험관을 하고 있는데, 여전히 객체지향과 양파 아키텍처 방식으로 추상화를 upfront로 쌓는 법을 배움
      이건 소프트웨어 개발에서 최악에 가까운 주문 중 하나임. 더 나쁜 건 이런 것들을 종교 수준으로 배운다는 점임. 이상한 건, 지난 수년간 전문가들이 소프트웨어를 쓰는 방식은 많이 발전했다는 것임. 말했듯 추상화가 모든 것에 본질적으로 나쁜 건 아님. SQL 데이터베이스에 들어가는 전형적인 데이터에 updated, updated_by 같은 필드를 담는 기본 클래스가 없는 건 상상하기 어렵기도 함. 하지만 일반적으로는 정말 강제되지 않는 한 추상화를 거의 쓰지 않음. 그런데 학계에서는 내가 25년 전에 배운 것과 정확히 같은 커리큘럼을 아직도 가르침. 학생들이 멋진 UML로 거대한 추상화를 만들고 코드로 구현하는 능력을 채점하고 있으면 참 이상함. 그들 중 90%는 다시는 UML 다이어그램 하나도 보지 않을 텐데 말임. 적어도 내가 있는 작은 영역에서는 그럴 것임. 그래도 현실은 현실임
    • 내가 실제로 Git을 쓰기 시작한 유일한 이유는 magit이었음
      모든 것에 명령줄 수준의 “포셀린”이 있으면 좋겠음. 표준 --help=ui 출력과 dialog 스타일 인터페이스가 있으면 자동화할 수 있을 것 같음. 복잡성에 압도된다기보다는, 활용할 수 있는 능동적 근육 기억의 양에는 한계가 있고 어딘가에서 잘라내야 한다는 문제에 가까움