# 아서 휘트니의 C 코드를 읽으며 똑똑해지기 (2024)

> Clean Markdown view of GeekNews topic #24133. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24133](https://news.hada.io/topic?id=24133)
- GeekNews Markdown: [https://news.hada.io/topic/24133.md](https://news.hada.io/topic/24133.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-11-04T15:33:07+09:00
- Updated: 2025-11-04T15:33:07+09:00
- Original source: [needleful.net](https://needleful.net/blog/2024/01/arthur_whitney.html)
- Points: 3
- Comments: 1

## Topic Body

- **Arthur Whitney**가 만든 50줄짜리 **K 언어 인터프리터 C 코드**를 분석하며, 그의 독특한 코딩 스타일을 해석한 기록  
- 코드에는 **매크로 기반의 압축 문법**, **비표준 C 확장**, **암묵적 인자 사용** 등 일반적인 C 코드와 다른 실험적 구조가 다수 포함  
- 작성자는 각 매크로와 함수의 의미를 직접 해석하며, **APL 계열 언어의 철학**과 **코드 밀도의 장단점**을 탐구  
- 코드의 장점으로는 **짧은 길이와 높은 구성력**, 단점으로는 **비표준 문법과 가독성 저하**를 지적  
- 결론적으로, 이 코드는 “짧게 쓰는 법”보다 **문제를 완전히 이해한 뒤 코드를 쓰는 사고방식**의 중요성을 보여주는 사례로 평가됨  

---
### Arthur Whitney와 그의 코드
- Arthur Whitney는 **A, K, Q 언어**와 **kdb, Shakti** 데이터베이스를 설계한 컴퓨터 과학자  
  - kdb는 금융권에서 사용되는 **초고속 시계열 데이터베이스**, Shakti는 그보다 빠른 버전으로 **1조 행 규모 데이터셋**을 처리하도록 설계됨  
- 그의 언어들은 **APL의 영향을 강하게 받은 배열 기반 언어**로, 간결성과 수학적 표현력을 중시함  
- 글의 초점은 금융 응용이 아니라, **휘트니가 작성한 C 코드의 독특한 스타일**을 분석하는 데 있음  

### 50줄짜리 K 인터프리터의 구조
- 공개된 [ksimple](https://github.com/kparc/ksimple) 리포지토리에는 휘트니가 며칠 만에 작성한 **약 50줄의 C 인터프리터**가 포함  
- 코드의 핵심은 `a.h`와 `a.c` 두 파일로 구성되어 있으며, **매크로를 통한 함수 정의 축약**과 **포인터를 정수처럼 사용하는 구조**가 특징  
- `typedef char*s,c;` 구문을 통해 `s`를 문자열 포인터, `c`를 문자형으로 정의  
- `s Q=(s)128;`은 포인터를 정수처럼 사용한 예로, 코드 전반에서 **Q가 오류 상태를 나타내는 특수 값**으로 쓰임  
- `({e;})` 형태의 **statement expression**과 `?:` 연산자 등 **GCC 확장 문법**이 다수 사용됨  

### 주요 매크로와 함수의 의미
- `#define _(e...) ({e;})` : 여러 문장을 하나의 표현식으로 묶는 매크로  
- `#define i(n,e)` : 반복문 축약 표현, `for` 루프를 한 줄로 표현  
- `#define Q(e)` 등은 **에러 처리 매크로**, `Qr`, `Qd`, `Qz`는 각각 rank, domain, not-yet-implemented 오류를 반환  
- `_s`, `_i`, `f`, `F` 매크로는 **함수 선언을 간소화**하며, 암묵적으로 인자 `x`, `a`를 사용  
- `ax`, `ix`, `nx` 등은 **데이터 타입 판별 및 인덱싱 매크로**, `ax`는 “x가 원자(atom)인지”를 판단  
- `f(w,write(1,ax?&x:x,ax?1:strlen(x));x)`는 **출력 함수**, 원자면 문자로, 벡터면 문자열로 출력  

### 인터프리터의 동작 방식
- `m(x)` 함수는 **메모리 할당 및 길이 정보 포함 포인터 생성**, 벡터의 최대 길이는 255바이트  
- `g(a,v)` 매크로는 **원자/벡터 연산을 통합 처리**, `not`, `sub`, `At`, `_A` 등의 함수가 이를 기반으로 정의  
- `G(f,o)` 매크로는 **이항 연산자 함수 자동 생성**, `<`, `==`, `+`, `*`, `&`, `|` 등의 연산을 지원  
- `cat`, `rev`, `cnt`, `Tak` 등은 **벡터 조작 함수**, `rev`는 `ind` 함수를 이용해 역순 인덱스를 생성  
- `e()` 함수는 **재귀적 평가기**, 문자열을 오른쪽에서 왼쪽으로 읽으며 **단일 문자 변수, 숫자, 연산자**를 처리  
- `main()`은 입력을 받아 `e()`로 평가 후 결과를 출력하는 **REPL 루프** 형태  

### 코드 스타일에 대한 평가
- **장점**
  - **조합 가능한 매크로**로 구성된 **간결한 원시 연산 집합**
  - **짧은 코드 길이**로 인해 스크롤 없이 전체 로직을 한눈에 파악 가능  
  - **고밀도 표현**을 통해 코드의 논리적 구조를 압축  
- **단점**
  - `char*`를 정수처럼 사용하는 **비의미적 타입 처리**
  - **ASCII 코드 직접 사용**, **복잡한 삼항 연산자**, **비표준 문법** 등으로 인한 가독성 저하  
  - **암묵적 인자**와 **짧은 변수명**으로 인해 의도 파악이 어려움  
- **중립적 요소**
  - GCC 전용 문법(`?:`, statement expression)은 흥미롭지만 **이식성 저하**
  - **암묵적 인자 사용**은 소규모 코드에서는 유용하나, 대규모 코드에서는 혼란 유발 가능  
  - **짧은 이름**은 익숙해지면 효율적이지만, 의미 전달력은 약함  

### 결론과 교훈
- 이 코드는 단순히 “짧게 쓰는 법”이 아니라, **문제를 완전히 이해한 뒤 코드를 작성하는 사고방식**을 보여줌  
- 휘트니의 코드는 **이미 완성된 수학적 모델을 코드로 옮긴 형태**, 즉 “생각을 코드로 표현한 결과물”  
- 작성자는 자신이 평소 **코드 안에서 문제를 해결하려는 습관**을 반성하며,  
  앞으로는 **코드 작성 전 개념적 모델링과 사고 정리의 중요성**을 강조  
- 최종적으로, 이 실험은 “코드를 읽는 능력”을 단련하고, **코드 밀도와 사고 명료성의 균형**을 탐구한 경험으로 정리됨  

### 향후 실험 아이디어
- 인터프리터 확장 실습 제안:
  - **부동소수점 벡터 지원**
  - **255개 이상 원소 처리**
  - **다자리 숫자 및 변수명**
  - **배열 리터럴과 공백 무시**
  - **메모리 관리 및 오류 표시 기능 추가**
  - **미구현 함수 완성**  
- 이러한 확장은 휘트니식 코드 스타일을 유지하면서 **실제 사용 가능한 언어로 발전시키는 실험**이 될 수 있음

## Comments



### Comment 45860

- Author: neo
- Created: 2025-11-04T15:33:08+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=45800777) 
- 이 코드의 매크로들은 **공통 연산을 압축**하기 위한 것임  
  나는 J Incunabulum을 먼저 읽고 나서 이 코드를 봤는데, C에 익숙한 프로그래머들이 중간부터 읽기 시작하면 초반의 매크로 정의들이 혼란을 줄 수 있음  
  매크로들이 서로를 기반으로 쌓이기 때문에 코드가 빠르게 **추상화의 사다리**를 오름  
  특히 `Iterate` 매크로(`i`)가 마음에 드는데, 장황한 루프를 한 글자로 줄여줌  
  이런 밀도 높은 코드가 읽기 어려운 이유는, 수십 줄 안에 수많은 추상화를 만들고 바로 사용하는 방식 때문임  
  그래서 한 글자씩 천천히 읽어야 함  
  수백 개의 얇은 파일로 구성된 대규모 코드베이스에서 일해본 입장에서는, 이런 극단적인 압축성이 오히려 신선하게 느껴짐
  - 나도 Incunabulum을 읽고 비슷한 생각을 했지만, 변수 이름을 **이모지로 바꿔보니** 훨씬 이해가 쉬워졌음  
    [이모지 버전 코드 이미지](https://imgur.com/F27ZNfk)를 보면 알 수 있듯, 문제의 일부는 **정보 밀도**뿐 아니라 **문자 형태(orthography)** 에 있음  
    현대 언어들은 식별자에 기호나 이모지를 쓰지 못하게 하는데, 이런 시각적 구분이 가능했다면 훨씬 읽기 쉬웠을 것임  
    또 대부분의 에디터가 구문별 색상(syntax highlighting)을 쓰지만, **토큰 기반 색상**(각 식별자마다 고유 색상)이 더 유용할 때가 많음  
    Sublime Text의 “hashed syntax highlighting”이 그 예임  
    이렇게 바꾸니 코드의 구조가 한눈에 들어왔음
  - 개발자들이 오히려 **거대한 코드베이스**를 선호하는 것 같음  
    나는 하위 디렉터리 없이 `grep *.[ch]`로 바로 찾을 수 있는 구조를 좋아함  
    Java 프로젝트는 특히 작은 파일이 너무 많고 내용이 빈약해서 찾기가 힘듦  
    IDE가 있으면 낫겠지만 나는 안 씀  
    Whitney는 인터뷰에서 모든 코드를 한 페이지에 담고 싶다고 했고, 그의 “IDE”는 **Windows 콘솔과 Notepad**라고 함

- Arthur Whitney의 C 코드를 이해하려면 먼저 **APL 계열 언어**를 배워야 함  
  그렇지 않으면 단순히 이상한 C 스타일로 보일 뿐임  
  Whitney는 C를 APL처럼 쓰려는 것임  
  공백이 없고, 한 글자 이름을 쓰며, 한 줄 함수로 구성된 스타일은 APL에서도 동일함  
  Pascal 프로그래머가 `#define begin {` 같은 걸 쓰는 것과 비슷하지만, Whitney는 그보다 훨씬 독창적임
  - APL 사용자 입장에서도 이건 이상하게 보임  
    Whitney가 만든 K 언어는 이런 스타일을 쓰지만, **한 줄 함수**는 전통적인 APL에서는 불가능했음  
    매크로나 삼항 연산자, 암묵적 변수명 같은 건 APL에 없음  
    APL의 본질은 **불변 배열 연산**인데, Whitney의 C 스타일은 그 철학과는 다름
  - “Pascal 프로그래머가 C로 넘어와서 `#define begin {` 하는 것 같다”는 말에 대해, “아, Stephen Bourne처럼 말이지”라고 농담함
  - 처음엔 함수형 언어처럼 보였는데, 곧 **C 전처리기의 공포**를 떠올리게 됨
  - 이미 글의 서두에서 “Whitney의 C는 APL에서 영감을 받았다”고 설명하고 있음  
    단순 요약 댓글이 많다는 지적임
  - J를 배우는 것도 괜찮을 것 같음  
    APL보다 접근성이 높고, **일반 키보드로 입력 가능한 기호**를 쓰기 때문임

- Shakti를 찾아보다가 [Wikipedia 링크](https://en.wikipedia.org/wiki/Shakti_(programming_language))가 `k.nyc`로 리디렉션되는 걸 봤는데, 페이지에는 **‘k’ 한 글자만** 있음  
  소스를 보니 정말 `&lt;div&gt;k&lt;/div&gt;`뿐이었음  
  이건 HTML 버전의 **Whitney식 미니멀리즘** 같음 — 불필요한 건 모두 제거하고, 컴파일러가 암묵적으로 처리하도록 맡긴 느낌임  
  - k

- 이 블로그 글은 Whitney의 코딩 스타일에 대한 평가와 상관없이 **훌륭한 분석글**임  
  작성자가 8시간 만에 쓴 것치고는 깊이가 있고, 결론 부분이 특히 인상적이었음  
  [원문 링크](https://needleful.net/blog/2024/01/arthur_whitney.html#:~:text=its%20tiny%20footprint.-,Conclusions,-I%20think%20I)

- Stephen Bourne이 C를 **Algol처럼 만들려던 시도**가 떠오름  
  [mac.h 예시](https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h)와  
  [expand.c 예시](https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/expand.c)를 보면 비슷한 감성이 느껴짐

- 모든 분야에는 “**best practice**”가 있지만, 그건 평균적인 경우에만 잘 맞음  
  특정 상황에서는 오히려 반대로 가는 게 더 나을 때도 있음  
  결국 **집단 지혜**는 기본값으로 삼되, 스스로 생각하기 시작하면 그 틈이 보이기 마련임
  - 그래서 “best practice”라는 표현이 싫음  
    사실은 **평균적인 수준의 절충안**일 뿐임  
    효율성과 성능을 희생하고 **유지보수성과 일관성**을 얻는 거래임
  - 좋은 제품을 만드는 것과 코드베이스의 **가독성이나 학습 곡선**은 별개임  
    한쪽이 잘된다고 해서 다른 쪽도 자동으로 따라오는 건 아님

- 코드에 대해 공격적으로 굴지 않고 **균형 잡힌 시각**을 보여줘서 좋았음  
  재미있게 읽었고, 나중에 다시 읽어볼 생각임

- 이런 코딩 스타일이 **특정 패러다임**인지 궁금했음  
  실제 프로젝트에서 이런 코드를 본 적은 거의 없고, “business card ray tracer” 같은 예외만 있음  
  Whitney가 만든 J 언어의 [소스 코드](https://github.com/jsoftware/jsource/blob/master/jsrc/j.c)도 비슷하게 **극도로 압축된 스타일**을 가짐
  - 맞음, 이건 Whitney의 **고유한 코딩 스타일**임  
    그의 배열 언어 인터프리터들에서 일관되게 쓰이며, 몇 페이지 안에 전체 구현을 담는 것으로 유명함  
    관련된 HN 논의들을 모아둔 [메타 댓글 링크](https://news.ycombinator.com/item?id=45800777#45805346)도 있음
  - “이런 코드를 실제로 본 적 없다”는 말에, “운이 좋았음”이라고 답함  
    이건 더 이상 C가 아니라, C 위에 새로 만든 **내부 DSL** 같은 언어임  
    C는 단지 첫 번째 **컴파일 타깃**일 뿐임
  - J, K 같은 **APL 계열 언어**와 유사함  
    비ASCII 기호를 쓰고, **극단적인 밀도**로 많은 정보를 한 페이지에 담을 수 있음  
    익숙해지면 추상화 계층이 줄어드는 장점도 있음
  - 비슷한 접근으로 만든 [co-dfns 관련 영상](https://www.youtube.com/watch?v=gcUWTa16Jc0)도 있음  
    C는 아니지만 비슷하게 **고밀도 스타일**로 작성됨
  - 농담처럼 “이건 OCC(Obfuscated C Code)”라고 부름

- 다음 매크로 정의들을 보면  
  ```c
  #define _(e...) ({e;})
  #define x(a,e...) _(s x=a;e)
  #define $(a,b) if(a)b;else
  #define i(n,e) {int $n=n;int i=0;for(;i<$n;++i){e;}}
  ```  
  이런 식으로 **공통 연산을 압축**하는 매크로들이지만, 너무 과감해서 “** 전쟁 범죄급 코드**”라고 농담함
  - 일부 매크로는 문법적으로도 잘못됨  
    예를 들어 `#define $(a,b) if(a)b;else`는 괄호가 없어 **버그 유발** 가능성이 큼  
    단순히 게으른 작성임

- 이런 매크로 사용은 좋은 예라고 생각함  
  겉보기엔 무섭지만, 사실 **간결한 선언형 C 스타일**임  
  다만 밀도가 높고, 생소한 매크로 문법 때문에 읽기 어렵게 느껴질 뿐임  
  “oo”는 아마 **무한대 오류 상태**나 디버그용 출력일 가능성이 있음
  - 나도 이런 매크로들이 유용하다고 생각함  
    `DO(n, code)` 같은 간단한 반복문 매크로가 있으면 좋겠음  
    작은 연산 단위(예: opcode, forth word, APL 연산자)를 한 줄로 표현하면 전체 구조를 한눈에 볼 수 있음  
    코드의 **‘사이 공간’** 에서 의미를 읽는 게 중요하다고 느낌
  - “좋은 매크로 사용”이라는 말에 단호히 “아니오”라고 반박함
