본문으로 건너뛰기

논문

Literate Programming

Donald E. Knuthdoi.org ↗

A. 서론 — 패러다임 전환 제안

  • 1970년대 구조적 프로그래밍(Structured Programming) 은 신뢰성과 가독성을 높였으나, Knuth는 이것만으로 충분하지 않다고 주장

  • 새로운 모토: 프로그램을 인간을 위한 문학 작품으로 간주하라

    • “컴퓨터에게 무엇을 하라고 지시하는 것”이 아니라, “사람에게 컴퓨터가 무엇을 해야 하는지 설명하는 것”으로 관점 전환
  • Literate Programmer의 역할: 에세이스트처럼 작동

    • 변수 이름을 신중하게 선택하고 의미를 설명

    • 인간의 이해에 최적인 순서로 개념을 도입

    • 형식적·비형식적 방법을 함께 사용

  • Knuth 본인의 경험: WEB으로 작성한 프로그램은 기존 방식보다 설명도 더 좋고, 품질도 더 높았음

  • “Literate Programming”이라는 용어 선택에는 의도적인 사회적 압박 포함 — “illiterate program을 쓴다고 인정하고 싶은 사람은 없다”


B. WEB 시스템 소개

WEB이란?

  • Stanford University에서 개발된 이중 언어 시스템(bilingual system)

  • 두 언어의 결합:

    1. 문서 포매팅 언어: TEX (대체 가능: Scribe, Troff 등)

    2. 프로그래밍 언어: PASCAL (대체 가능: ADA, C, LISP, FORTRAN 등)

  • WEB 자체에 매크로 처리 기능이 있어 PASCAL의 한계를 상당 부분 극복

두 가지 처리 흐름 (Figure 1 기준)

text

          `┌─ WEAVE ─▶ .TEX ─▶ TEX ─▶ .DVI (인쇄용 문서) .WEB 소스 ────┤               └─ TANGLE ─▶ .PAS ─▶ PASCAL ─▶ .REL (실행파일)`
  • WEAVE: .WEB → .TEX → 타이포그래피가 적용된 인쇄용 문서 생성

  • TANGLE: .WEB → .PAS → 컴파일 가능한 PASCAL 코드 생성

  • 소스 단일화: 문서와 코드가 동일한 .WEB 파일에서 생성 → 항상 일관성 유지

  • WEB 사용자 매뉴얼은 10페이지 미만 (TEX + PASCAL을 아는 사람이면 바로 학습 가능)


C. 예제 — 소수 출력 프로그램

프로그램 개요

  • Edsger Dijkstra의 “step-wise program composition” 예제를 WEB 스타일로 재작성

  • 목적: 첫 번째 1,000개의 소수를 표 형식으로 출력

WEB의 핵심 구조 원칙

  • 섹션(Section) 단위로 분할, 각 섹션은 일련번호 부여 (§1, §2, …)

  • 각 섹션 구성:

    1. 주석(Commentary): 해당 섹션의 의도·동기를 자연어로 설명

    2. 매크로 정의(Macro Definitions): 선택적

    3. 프로그램 텍스트(Program Text): 실제 코드 (PASCAL 또는 섹션 참조)

  • Angle bracket 표기 ⟨섹션명 번호⟩: 다른 섹션의 코드를 삽입하는 참조 방식

    • 예: ⟨Fill table p with the first m prime numbers 11⟩ → §11의 코드로 확장
  • +≡ 표기: 동일한 이름의 섹션에 코드를 이어붙임 (점진적 확장)

설계 결정들이 명시적으로 기술되는 방식 (예시)

섹션 결정 내용
§3 소수 생성과 출력을 분리
§4 p 배열: boolean 배열 대신 integer 배열 선택
§5 출력 포맷: rr=50행, cc=4열, ww=10 자리
§14 p₁=2이므로 짝수 스킵, j를 홀수만 증가
§17 j의 최소 소인수는 √j 이하 → ord 변수로 검사 범위 최소화
§21 Bertrand의 가정(p_{k+1} < 2p_k)에 의해 pord는 항상 이미 계산됨
§24 나눗셈 없이 소인수 탐지: mult[] 보조 배열(에라토스테네스의 체 병렬화)

자동 생성 인덱스

  • WEAVE는 모든 식별자의 정의 섹션과 사용 섹션을 자동 인덱싱

  • 정의된 섹션 번호는 밑줄 표시 (수동 마킹 필요)

  • 키 개념(‘Bertrand’s postulate’, ‘Output format’ 등)도 인덱스에 포함 가능


D. WEB 소스 파일 구조

주요 명령 기호

기호 역할
@ WEB escape 문자
@ (@ + 공백) 일반 섹션 시작
@* 주요 섹션 시작 (굵은 제목, 목차에 포함, 페이지 상단 시작)
@p PASCAL 프로그램 텍스트 시작
@<..@> 섹션 이름 참조 (angle bracket)
@> WEB 명령 인수 종료
@^ 로마체 인덱스 항목 시작
@. 타이프라이터체 인덱스 항목 시작
@d 매크로 정의
@& 두 텍스트를 공백 없이 연결 (concatenation)
`
@{ / @} TANGLE이 제거하지 않는 특수 중괄호 (조건부 코드 비활성화에 활용)

WEB 이중 언어 특성

  • TEX 주석 안에서 |output|처럼 수직바로 감싸면 PASCAL 포맷 적용

  • PASCAL 코드 안에서 TEX 수식·설명 삽입 가능

  • TANGLE 출력(PASCAL)은 인간이 읽도록 설계되지 않음 — 모든 밑줄 제거, 대문자 변환, 섹션 경계만 {8:} / {:8} 형식 주석으로 표시


E/F. TANGLE · WEAVE 출력물 비교

구분 TANGLE 출력 (.PAS) WEAVE 출력 (.TEX)
대상 독자 PASCAL 컴파일러 인간
가독성 매우 낮음 높음 (타이포그래피 적용)
주석 섹션 경계 주석만 삽입 전체 설명 포함
포맷 대문자화, 밑줄 제거 들여쓰기·이탤릭·볼드 자동 처리
목적 실행파일 생성 프로그램 이해·유지보수
  • WEAVE 출력 TEX 파일은 직접 읽기 매우 어려움 → WEAVE가 타이포그래피를 자동 처리해준다는 것이 장점

G. 추가 기능 (WEB83)

  1. WEAVE 포맷팅 오버라이드: 줄바꿈 강제, 예약어·식별자 역할 교체 가능

  2. TANGLE 공백 제어: @&로 텍스트 연결 (예: x + 3x3), verbatim 출력

  3. 진법 상수: 8진수·16진수 상수 지원 (TANGLE이 10진수로 변환)

  4. ASCII 상수: 이중 따옴표 문자("A") → ASCII 코드 정수로 변환 → 이식성 향상

  5. 문자열 풀(String Pool): 멀티 문자 문자열을 정수로 인코딩, 체크섬으로 일관성 검증

  6. 수치 매크로(Numeric Macro): 컴파일 타임 산술 지원 (PASCAL의 컴파일 타임 연산 불가 문제 해결)

    • 예: 배열 경계 0..n-1, case 레이블 20+3 표현 가능

H. 의도적으로 뺀 기능 (Occam’s Razor)

  • 조건부 매크로 없음: Boolean 평가 기반 조건 출력 지원 안 함

    • 대안: stat/tats처럼 begin/end 역할 매크로로 코드 블록을 주석처리
  • 매크로 파라미터는 최대 1개

    • 다중 파라미터는 체이닝으로 표현 가능: mac(a)(b)m[a*r+b]

    • 매크로 이름 자체를 파라미터로 사용 가능: two_cases(reset_file) → 파일 배열 우회

  • 단순성 유지 원칙: 불필요한 복잡성 배제 → 언어 학습 비용 최소화


I. 이식성 (Portability)

WEB의 이식성 강점

  • TEX은 DEC-10 → IBM, CDC, XEROX, HP 등 매우 다양한 플랫폼으로 이식 성공

  • “이 복잡도의 소프트웨어가 이렇게 많은 기종에 이식된 사례는 없었다”

  • 이식 병목: PASCAL 컴파일러 품질 불균일 (시스템 프로그래밍 고려 부재)

부트스트래핑 순서

  1. TANGLE.PAS를 PASCAL 컴파일러로 컴파일 → TANGLE 실행 파일 획득

  2. TANGLETANGLE.WEB 처리 → 출력이 TANGLE.PAS와 일치 확인

  3. TANGLEWEAVE.WEB 처리 → WEAVE 획득

  4. 이후 모든 WEB 프로그램(TEX 포함) 동일 방식으로 설치

변경 파일(Change File) 메커니즘

  • TEX.WEB + TEX.CH 두 입력 파일 사용

  • CH 파일 형식: “x₁…xₘ를 y₁…yₙ로 교체” (m줄 매칭 후 n줄로 치환)

  • 핵심 이점 2가지:

    1. 마스터 파일 불변: TANGLE.WEB는 모든 플랫폼이 동일하게 공유

    2. 독립적 업데이트: WEB 파일이 바뀌어도 기존 CH 파일이 대부분 그대로 동작, 반대도 성립

  • TANGLE의 약 190개 섹션 중 플랫폼 의존적 섹션은 약 15개만 변경 필요


J. 프로그램을 “웹(Web)“으로 보기

Top-down vs. Bottom-up의 대립 극복

방식 장점 단점
Top-down 전체 구조가 명확 끝까지 완성 전까지 아무것도 확정되지 않음
Bottom-up 점차 강력한 도구를 손에 쥠 전체 구성을 마지막까지 미루게 됨
WEB 최적 노출 순서로 자유롭게 기술 없음
  • WEB의 핵심 통찰: 프로그램은 트리가 아니라 웹(web) — 계층 구조보다 구조적 관계가 중요

  • 프로그래머는 “심리적으로 올바른 순서(psychologically correct order)“로 코드를 기술

  • TANGLE이 PASCAL 컴파일러가 요구하는 순서로 자동 재배열

WEB이 코드 품질을 높이는 이유

  • 기존 언어의 문제: 서브루틴 내 에러 처리 코드가 짧은 주 로직에 비해 길어 보이면 심리적으로 에러 처리를 최소화하게 됨

  • WEB의 해결: 각 섹션이 독립적이므로 에러 처리 섹션은 그 섹션 자체로서 완결

    • 에러 처리를 충분히 작성하는 것이 자연스럽게 됨
  • 결과: 각 부분이 그것이 마땅한 크기를 가질 수 있음 → 코드 전체 가독성 훼손 없음


K. 스타일 가이드라인

매크로 vs. 섹션 이름

  • 짧은 것 → 파라미터 없는 매크로로 표현

  • 긴 것 → 이름 붙인 섹션으로 표현

섹션 명명 규칙

  • 섹션 이름: 명령형 동사로 시작 (⟨Print table p⟩)

  • 섹션 주석: 선언적으로 작성 (“Now that appropriate variables have been introduced…”)

  • 이름에 모든 전제조건을 담으려 하지 말 것 → 형식·비형식 균형

goto 문에 대한 견해

  • WEB에서는 의미 있는 레이블과 함께 goto 사용이 정당화될 수 있음

  • 예: goto found, goto not_found → 추상적 의미가 명확하면 오히려 읽기 쉬움

  • PASCAL의 goto 사용 불편함(숫자 레이블, 선행 선언 등)은 WEB 수치 매크로로 우회

PASCAL의 아쉬운 점 (WEB과의 마찰)

  • 로컬 변수를 프로시저 중간에 선언 불가 → ⟨Local variables for xyzzy⟩ 섹션으로 우회

  • 세미콜론 위치 처리 불편 → 관행 체득 필요


L. 경제성 분석

컴퓨터 비용

  • TANGLE 실행 시간 ≈ PASCAL 컴파일 시간 → 추가 비용 미미

  • TEX 타이포그래핑 비용이 가장 큰 부분 (예: 60페이지 문서 ≈ 4분)

  • 실무 관행: 최신 WEB 소스를 직접 읽고, 하루 1~2회만 전체 문서 재생성

생산성

  • 총 작성 + 디버깅 시간은 ALGOL/PASCAL과 동등 (문서 품질은 월등히 높음에도 불구하고)

  • 이유: WEB는 설명 모드(expository mode)를 강제 → 수업 중 칠판 코딩처럼 생각이 명확해짐 → 버그 발생률 감소 → 디버깅 시간 감소

  • 부수 효과: 아름다운 프로그램을 공유하고 싶은 욕구 발생 → “Webs”라는 저널 탄생 가능성까지 상상


M. 관련 연구 및 영향

인물 기여
George Forsythe (1966) “유용한 알고리즘은 중요한 지식의 기여” → 프로그램을 문학으로 보는 시각의 영감
Pierre-Arnoul de Marneffe Holon Programming — WEB의 가장 직접적인 선구자 (Koestler의 복잡계 구조에서 영감)
Edwin Towster 독립적으로 유사한 시스템 개발
Dijkstra, Hoare, Dahl, Wirth 추상화의 중요성 인식
Peter Naur 형식·비형식 방법 균형의 중요성
Tony Hoare (1978) TEX 소스 공개 제안 → WEB 개발의 직접적 계기
Luis Trabb Pardo 초기 DOC 시스템 스타일 개발 협력
Ignacio Zabala DOC 시스템으로 TEX PASCAL 구현 → 이식성 실험
Harold Thimbleby Cweb 개발 (Troff/Nroff + C 기반)

개발 연혁

시기 사건
1979 봄 DOC 프로토타입 개발
1981 봄 WEB 설계 (TANGLE.WEB, WEAVE.WEB 작성 약 6주)
1981 9월 이식성 실험 기반으로 WEB 현재 형태 완성
1982 9월 WEB Version 1 공개
1983 9월 WEB83 완성 (Stanford CS Report CS980으로 전체 문서 공개)

N. 회고와 전망

한계와 솔직한 인정

  • Knuth 자신의 경험이 모든 프로그래머에게 적용되지 않을 수 있음

  • WEB의 대상 사용자: 복수 언어를 동시에 다룰 수 있는 컴퓨터 과학자 (고등학생·취미 프로그래머 대상 아님)

  • WEB 오류 유형: WEB 문법 오류 + TEX 문법 오류 + PASCAL 문법 오류 + 알고리즘 오류 → 구분 능력 필요

WEB의 미래에 대한 제안

  • 통합 컴파일러: TANGLE + 컴파일러를 단일 시스템으로 통합

  • 런타임 디버깅: WEB 소스 언어로 직접 디버깅 가능한 환경

  • 모듈 독립 컴파일: WEB 섹션 단위 독립 컴파일

  • 그래픽 워크스테이션 활용: 관심 섹션만 선택적으로 TEX 렌더링 (전체 문서 재생성 불필요)

  • Literate Programming이 확산된다면 Pulitzer Prize를 받는 컴퓨터 프로그램이 등장할 수도 있다고 상상


핵심 인사이트 정리

  1. 코드는 컴퓨터보다 사람을 위해 먼저 쓰여야 한다 — 이것이 품질을 높인다

  2. 최적 순서는 top-down도 bottom-up도 아닌, 심리적으로 자연스러운 순서다 — WEB이 TANGLE로 재배열해줌

  3. 문서화는 비용이 아니라 투자다 — 추가 설명 시간이 디버깅 시간 감소로 상쇄됨

  4. 각 부분이 마땅한 크기를 가질 때 에러 처리가 충분해지고 전체 코드 품질이 올라간다

  5. 이식성과 변경관리는 마스터 파일(WEB) + 변경 파일(CH)의 분리로 우아하게 해결된다

  6. 단순성(Occam’s Razor): 기능을 제거하는 결정도 설계의 일부다[academic.oup]​[ppl-ai-file-upload.s3.amazonaws]​