A. 서론 — 패러다임 전환 제안
-
1970년대 구조적 프로그래밍(Structured Programming) 은 신뢰성과 가독성을 높였으나, Knuth는 이것만으로 충분하지 않다고 주장
-
새로운 모토: 프로그램을 인간을 위한 문학 작품으로 간주하라
- “컴퓨터에게 무엇을 하라고 지시하는 것”이 아니라, “사람에게 컴퓨터가 무엇을 해야 하는지 설명하는 것”으로 관점 전환
-
Literate Programmer의 역할: 에세이스트처럼 작동
-
변수 이름을 신중하게 선택하고 의미를 설명
-
인간의 이해에 최적인 순서로 개념을 도입
-
형식적·비형식적 방법을 함께 사용
-
-
Knuth 본인의 경험: WEB으로 작성한 프로그램은 기존 방식보다 설명도 더 좋고, 품질도 더 높았음
-
“Literate Programming”이라는 용어 선택에는 의도적인 사회적 압박 포함 — “illiterate program을 쓴다고 인정하고 싶은 사람은 없다”
B. WEB 시스템 소개
WEB이란?
-
Stanford University에서 개발된 이중 언어 시스템(bilingual system)
-
두 언어의 결합:
-
문서 포매팅 언어: TEX (대체 가능: Scribe, Troff 등)
-
프로그래밍 언어: 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, …)
-
각 섹션 구성:
-
주석(Commentary): 해당 섹션의 의도·동기를 자연어로 설명
-
매크로 정의(Macro Definitions): 선택적
-
프로그램 텍스트(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)
-
WEAVE 포맷팅 오버라이드: 줄바꿈 강제, 예약어·식별자 역할 교체 가능
-
TANGLE 공백 제어:
@&로 텍스트 연결 (예:x+3→x3), verbatim 출력 -
진법 상수: 8진수·16진수 상수 지원 (TANGLE이 10진수로 변환)
-
ASCII 상수: 이중 따옴표 문자(
"A") → ASCII 코드 정수로 변환 → 이식성 향상 -
문자열 풀(String Pool): 멀티 문자 문자열을 정수로 인코딩, 체크섬으로 일관성 검증
-
수치 매크로(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 컴파일러 품질 불균일 (시스템 프로그래밍 고려 부재)
부트스트래핑 순서
-
TANGLE.PAS를 PASCAL 컴파일러로 컴파일 → TANGLE 실행 파일 획득 -
TANGLE로TANGLE.WEB처리 → 출력이TANGLE.PAS와 일치 확인 -
TANGLE로WEAVE.WEB처리 → WEAVE 획득 -
이후 모든 WEB 프로그램(TEX 포함) 동일 방식으로 설치
변경 파일(Change File) 메커니즘
-
TEX.WEB+TEX.CH두 입력 파일 사용 -
CH 파일 형식: “x₁…xₘ를 y₁…yₙ로 교체” (m줄 매칭 후 n줄로 치환)
-
핵심 이점 2가지:
-
마스터 파일 불변:
TANGLE.WEB는 모든 플랫폼이 동일하게 공유 -
독립적 업데이트: 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를 받는 컴퓨터 프로그램이 등장할 수도 있다고 상상
핵심 인사이트 정리
-
코드는 컴퓨터보다 사람을 위해 먼저 쓰여야 한다 — 이것이 품질을 높인다
-
최적 순서는 top-down도 bottom-up도 아닌, 심리적으로 자연스러운 순서다 — WEB이 TANGLE로 재배열해줌
-
문서화는 비용이 아니라 투자다 — 추가 설명 시간이 디버깅 시간 감소로 상쇄됨
-
각 부분이 마땅한 크기를 가질 때 에러 처리가 충분해지고 전체 코드 품질이 올라간다
-
이식성과 변경관리는 마스터 파일(WEB) + 변경 파일(CH)의 분리로 우아하게 해결된다
-
단순성(Occam’s Razor): 기능을 제거하는 결정도 설계의 일부다[academic.oup][ppl-ai-file-upload.s3.amazonaws]