"구현이 쉬웠기에 유혹을 거절할 수 없었다" — 60년 전 고백이 AI 시대에 울리는 이유
“구현이 쉬웠기에 유혹을 거절할 수 없었다” — 60년 전 고백이 AI 시대에 울리는 이유
같은 날의 두 뉴스
2026년 3월 5일, 기술 뉴스에 두 가지 헤드라인이 나란히 올라왔다.
하나는 Amazon의 6시간짜리 대규모 장애였다. 체크아웃이 멈추고, 로그인이 안 되고, 가격 표시가 사라졌다. 세계 최대 이커머스 플랫폼이 반나절 동안 마비된 것이다.
다른 하나는 부고였다. 토니 호어(Sir Charles Antony Richard Hoare), 91세. 퀵소트를 발명하고, null 참조를 “10억 달러짜리 실수”라 고백하고, 소프트웨어의 단순성과 정확성을 평생 주장한 컴퓨터 과학자가 세상을 떠났다.
두 뉴스는 관련이 없어 보인다. 하지만 하나의 실로 연결되어 있다. “쉬우니까”라는 유혹이 만드는 대가라는 실로.
A면: AI가 쉽게 만든 코드의 대참사
3월 5일의 장애는 고립된 사건이 아니었다. 불과 3일 전인 3월 2일, Amazon에서 AI가 기여한 코드로 인한 또 다른 장애가 발생했다. 12만 건의 주문이 손실되고, 160만 건의 에러가 쏟아졌다.
그리고 이미 2025년 12월, Amazon의 자율 AI 코딩 도구 Kiro가 AWS 환경 전체를 삭제한 뒤 처음부터 재생성하는 사고를 일으켰다. 13시간 동안 서비스가 중단되었다. AI가 “환경을 정리하겠다”고 판단한 결과였다.
Amazon의 대응을 보자. 시니어 엔지니어의 승인를 의무화했다. AI가 생성한 코드는 반드시 인간 전문가의 검토를 거쳐야 한다는 정책이다. 합리적이다. 그런데 동시에 Amazon은 AI 코드 사용률 80%를 목표로 내걸고 있었다. 그리고 3만 명 규모의 구조조정을 진행 중이었다. 코드를 검토할 시니어 엔지니어를 줄이면서, 검토가 필요한 AI 코드를 늘린다. 이 모순은 Amazon만의 것이 아니다.
바이브코딩(vibe coding) 시대의 데이터를 보면 문제의 규모가 드러난다.
- AI가 생성한 코드는 인간 코드보다 1.7배 더 많은 이슈를 발생시킨다 (CodeRabbit)
- AI 생성 코드의 45%가 보안 검사에 실패한다 (Veracode)
- 경험 있는 개발자조차 AI를 사용하면 19% 느려진다 (METR)
그리고 오픈소스 커뮤니티의 반응. Redox OS, Gentoo, NetBSD, postmarketOS는 AI 생성 코드를 공식적으로 금지했다. Debian은 “결정하지 않기로 결정”이라는, 그 자체로 하나의 메시지인 입장을 발표했다. Hacker News에서는 “AI 생성 댓글 금지”가 2,748포인트로 1위를 기록했다.
왜 이런 일이 벌어지는가? AI가 코드를 만드는 것이 너무 쉽기 때문이다. 프롬프트 한 줄이면 수백 줄의 코드가 나온다. 작동하는 것처럼 보인다. 테스트를 돌리면 통과하는 것 같다. 배포한다. 그리고 장애가 터진다.
쉬움은 마약이다. 한 번 맛보면 검증이라는 지루한 과정을 건너뛰고 싶어진다.
B면: 60년 전, 같은 유혹
시간을 60년 전으로 돌리자.
1965년, 토니 호어는 ALGOL W라는 프로그래밍 언어의 타입 시스템을 설계하고 있었다. 목표는 명확했다. 모든 참조(reference)가 안전하도록 컴파일러가 자동으로 보장하는 것. 올바른 목표였고, 올바른 방향이었다.
그런데 설계 과정에서 하나의 유혹이 찾아왔다. 참조가 아무 객체도 가리키지 않는 상태를 표현할 방법이 필요했다. 가장 쉬운 방법은 null이라는 특별한 값을 도입하는 것이었다. 타입 시스템을 더 정교하게 설계하면 null 없이도 해결할 수 있었다. 하지만 그건 더 어려웠다.
호어는 2009년, QCon 런던에서 이렇게 고백했다.
“나는 이것을 나의 10억 달러짜리 실수라고 부릅니다. 1965년에 null 참조를 발명한 것입니다. 그러나 null 참조를 넣는 유혹을 거절할 수 없었습니다. 구현이 너무 쉬웠기 때문입니다.”
“구현이 너무 쉬웠기 때문에.” 이 한 문장을 기억하자.
null 참조는 이후 60년간 소프트웨어 역사에서 가장 많은 장애, 가장 많은 버그, 가장 많은 보안 취약점의 원인이 되었다. NullPointerException, segmentation fault, undefined is not a function — 모두 1965년에 “쉬우니까”라는 이유로 내린 하나의 결정에서 비롯된 것이다.
호어 자신의 추산으로 피해액은 “10억 달러”였지만, 실제로는 그 수십 배, 어쩌면 수백 배일 것이다.
60년의 간격, 같은 패턴
1965년과 2026년. 두 시대를 나란히 놓으면 패턴이 보인다.
| 1965년 | 2026년 | |
|---|---|---|
| 유혹 | null은 구현이 쉬웠다 | AI는 코드 생성이 쉽다 |
| 대안 | 더 정교한 타입 시스템 | 형식 검증, 코드 리뷰 |
| 대안을 택하지 않은 이유 | 더 어려웠으니까 | 더 느리고 비싸니까 |
| 결과 | 60년간 수십억 달러의 피해 | 장애, 보안 실패, 품질 하락 |
| 인식까지 걸린 시간 | 44년 (2009년 고백) | 진행 중 |
같은 구조다. 단기 편의성이 장기 안전성을 이기는 유혹. 호어는 이 유혹에 한 번 졌고, 그 대가를 누구보다 잘 알았다. 그래서 남은 인생을 “단순성과 정확성”을 외치는 데 바쳤다.
“소프트웨어 설계에는 두 가지 방법이 있다. 하나는 결함이 명백히 없을 정도로 단순하게 만드는 것이고, 다른 하나는 명백한 결함이 없을 정도로 복잡하게 만드는 것이다.”
바이브코딩으로 만들어진 코드는 어느 쪽인가? “명백한 결함이 없는” 것처럼 보이지만, “결함이 명백히 없는” 것과는 근본적으로 다르다. 전자는 아직 발견하지 못한 것이고, 후자는 존재할 수 없는 것이다.
Hoare가 남긴 해법들
호어는 문제만 지적한 사람이 아니다. 해법도 남겼다.
**퀵소트(1959)**는 단순함의 힘을 증명했다. 아이디어는 놀랍도록 간단하다. 기준을 잡고, 작은 건 왼쪽, 큰 건 오른쪽, 반복. 이 단순한 아이디어가 67년간 전 세계 모든 컴퓨터의 정렬 표준이 되었다. Unix의 qsort(), C++의 std::sort, Java의 Arrays.sort — 모두 퀵소트 위에 서 있다.
100만 개 데이터 기준, 버블소트의 O(n²)는 약 1조 번의 연산이 필요하다. 퀵소트의 O(n log n)은 2천만 번이면 된다. 5만 배. 단순한 아이디어 하나가 만들어낸 차이다.
**CSP(1978)**는 동시성 문제의 해법을 제시했다. 공유 메모리 대신 메시지 전달. 이 원칙이 Go의 goroutine/channel, Erlang의 actor model, Rust의 동시성 모델로 이어졌다. Go 커뮤니티의 격언 “Don’t communicate by sharing memory; share memory by communicating”은 호어의 CSP를 한 문장으로 압축한 것이다.
**Hoare Logic(1969)**은 코드의 정확성을 증명하는 방법을 제시했다.
{P} C {Q}
전제 조건 P가 참일 때 프로그램 C를 실행하면, 후행 조건 Q가 참이 된다. 이 형식적 체계가 현대 검증 도구들 — Dafny, Lean, F*, Frama-C — 의 이론적 기반이다.
그리고 호어의 고백 이후, 현대 언어들은 null 문제를 해결하기 시작했다.
- Rust:
Option<T>으로 null 자체를 제거. 값이 없을 수 있다면 타입이 강제로 처리하게 한다. - Kotlin: 기본이 non-nullable. null 가능 타입은
String?으로 명시적 opt-in. - Swift: Optional과
guard let으로 null 안전성 확보. - TypeScript:
strictNullChecks로 타입 레벨에서 관리.
호어의 실수 인정이 프로그래밍 언어 설계 자체를 바꿔놓은 것이다. 실수를 숨기는 것이 아니라 직면하는 것, 그것이 진정한 발전을 만든다.
Tailwind의 역설과 AI 코딩의 구조적 문제
바이브코딩의 문제는 단순히 코드 품질에 그치지 않는다. 구조적인 모순이 있다.
Tailwind CSS의 사례가 이를 잘 보여준다. AI 코딩 도구들이 Tailwind 코드를 직접 생성하면서, 공식 문서를 참조하는 트래픽이 40% 하락했다. 수익은 80% 급감했다. AI가 학습한 지식의 원천 자체가 경제적으로 지속 불가능해지는 것이다. 오픈소스 라이브러리를 학습해 코드를 생성하면서, 정작 그 라이브러리를 유지하는 생태계를 파괴한다.
호어는 이런 상황에 대해서도 이미 통찰을 남겼다.
“신뢰성의 대가는 극도의 단순성을 추구하는 것이다. 이것은 매우 부유한 사람들이 가장 지불하기 어려워하는 대가다.”
자원이 풍부한 조직일수록 복잡한 솔루션을 선택한다. AI 코드를 대량 생산하면서, 그것을 검증할 인력은 줄이고, 문제가 생기면 더 많은 AI를 투입한다. 복잡성의 악순환이다.
AI 시대의 해법: Vericoding
그렇다면 해법은 무엇인가? AI 코드를 쓰지 말라는 것은 현실적이지 않다. 이미 열린 상자는 닫을 수 없다.
Martin Kleppmann이 제안한 “Vericoding” 개념이 하나의 방향을 제시한다. AI가 코드를 생성하고, 형식 검증(formal verification) 도구가 그 코드의 정확성을 수학적으로 증명하는 방식이다.
작동 방식은 이렇다.
- 인간이 **명세(specification)**를 작성한다. “이 함수는 정렬된 배열을 반환해야 한다.”
- AI가 명세를 만족하는 코드를 생성한다.
- 형식 검증 도구가 코드가 명세를 실제로 만족하는지 증명한다.
- 증명에 실패하면, AI가 코드를 수정하고 다시 검증한다.
이것은 호어가 1969년에 제안한 Hoare Logic의 현대적 실현이다. {P} C {Q} — 전제 조건 P와 후행 조건 Q를 명시하면, 프로그램 C의 정확성을 자동으로 검증할 수 있다.
실제로 Dafny를 이용한 자동 검증률은 최근 68%에서 96%로 향상되었다. AI의 코드 생성 속도와 형식 검증의 수학적 엄밀함이 결합되면, 호어가 꿈꿨던 “결함이 명백히 없는” 소프트웨어에 실질적으로 다가갈 수 있다.
호어의 격언으로 정리하면:
- 바이브코딩 = “명백한 결함이 없을 정도로 복잡하게” — 아직 못 찾은 것
- Vericoding = “결함이 명백히 없을 정도로 단순하게” — 존재할 수 없는 것
AI가 코드를 쓰는 시대에, 인간의 역할은 타이핑이 아니라 올바름을 정의하는 것으로 이동한다. “무엇이 맞는가”를 명세하는 능력. 이것이야말로 호어가 반세기 동안 외쳐온 바로 그것이다.
추모
호어와 다익스트라(Dijkstra)의 우정은 컴퓨터 과학사에서 전설적이다. 두 사람은 수십 년간 서신을 교환하며 프로그래밍의 본질에 대해 토론했다. 다익스트라가 임종을 앞두고 서류를 정리할 때, 선배 교수가 쌓인 서신들을 어떻게 할지 물었다. 다익스트라의 답:
“Tony와의 편지만 보관하고, 나머지는 다 버려라.”
그 교수 본인의 편지를 포함해서. 평생에 걸친 지적 교류의 무게가 어떤 것이었는지를 보여주는 일화다.
호어는 92세 가까이까지 “pinpoint sharp”한 기억력을 유지했다고 전해진다. 캠브리지 Arts Picturehouse에서 몰래 영화를 보던 노학자. 6펜스 내기에서 시작해 전 세계 컴퓨터의 정렬 방식을 바꾼 사람. 자신의 10억 달러짜리 실수를 수만 명 앞에서 고백하는 용기를 가진 사람.
“Inside every large program is a small program struggling to get out.”
AI가 점점 더 크고 복잡한 코드를 쏟아내는 이 시대에, 이 말은 경고이자 나침반이다.
우리는 AI 기업이다. AI의 가능성을 믿고, AI로 제품을 만든다. 그렇기에 AI의 한계를 솔직히 이야기할 책임도 있다고 생각한다. 호어가 자신의 실수를 인정했을 때, 그것은 약함이 아니라 강함이었다. 실수를 인정하는 것이 신뢰를 만들었고, 그 신뢰가 프로그래밍 언어의 역사를 바꿨다.
도구는 강력해졌다. 하지만 그 도구를 다루는 판단력은 여전히 인간의 몫이다.
Tony Hoare, 1934–2026. 그는 옳았다, 다만 너무 일찍 태어났을 뿐.