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

7 hours ago 2

  • 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 리포지토리에는 휘트니가 며칠 만에 작성한 약 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개 이상 원소 처리
    • 다자리 숫자 및 변수명
    • 배열 리터럴과 공백 무시
    • 메모리 관리 및 오류 표시 기능 추가
    • 미구현 함수 완성
  • 이러한 확장은 휘트니식 코드 스타일을 유지하면서 실제 사용 가능한 언어로 발전시키는 실험이 될 수 있음

Read Entire Article