- 이 글은 면접 상황에서 지원자가 단순한 FizzBuzz 문제를 람다 대수 기반의 순수 함수 조합자로 구현하려는 풍자적 서사를 담음
- 주인공은 JavaScript로 시작하지만, 점차 S, K, I 조합자를 정의하며 언어의 기본 구조를 스스로 재구성함
- 이어서 불리언, 수, 리스트, 문자열을 모두 조합자만으로 표현하고, Y 조합자를 통해 재귀를 구현함
- 최종적으로 FizzBuzz를 완전한 포인트 프리(point-free) 스타일로 완성하지만, 코드가 인간이 이해할 수 없는 수준으로 확장됨
- 이 글은 프로그래밍 언어의 본질과 추상화의 극단을 유머러스하게 탐구하며, 개발자 문화의 자기 풍자를 드러냄
면접의 시작: FizzBuzz와 조합자
- 이야기의 시작은 면접관 Dana가 지원자에게 FizzBuzz 문제를 풀어보라고 요청하는 장면으로 시작
- 지원자는 일반적인 반복문 대신 S와 K 조합자를 정의하며 문제를 풀기 시작
- Dana는 의아해하지만, 지원자는 “조금만 더 하면 된다”고 말하며 계속 진행
- 지원자는 I, B, C, W, T 등 다양한 조합자를 정의하며, 이를 새로운 언어의 기본 구성 요소로 사용
- 각 조합자는 함수 합성, 인자 교환, 자기 적용 등 람다 대수의 핵심 개념을 구현
- 코드 주석에는 “Bluebird, Cardinal, Warbler, Thrush” 등 조합자 이름의 별칭이 등장
불리언과 수의 정의
- 지원자는 TRUE, FALSE, NOT을 조합자만으로 정의하며 불리언 논리를 구축
- Dana는 “람다 대수냐”고 묻지만, 지원자는 “람다 대수는 너무 비대하다”고 답함
- 이어서 ZERO, SUCC, PRED, IS_ZERO 등을 정의하며 수 체계(Church numeral) 를 구성
-
SUCC는 후속자, PRED는 전임자, DECREMENT는 0 이하로 내려가지 않는 감소 연산을 구현
-
ONE부터 TEN까지의 숫자를 순차적으로 정의
재귀와 Y 조합자
- 지원자는 ADD 함수를 정의하며, 점차 포인트 프리(point-free) 형태로 변환
-
ADD_MAKER를 정의하고, 이를 Y 조합자로 감싸 재귀를 가능하게 함
- Dana는 “JavaScript에서도 재귀가 된다”고 지적하지만, 지원자는 “곧 JavaScript가 아닐 것”이라 답함
- JavaScript의 엄격한 평가(eager evaluation) 로 스택 오버플로가 발생하자, 지원자는 Skoobert라는 “게으른(lazy)” JS 인터프리터로 코드를 실행
산술, 리스트, 그리고 문자열
- 지원자는 SUBTRACT, MULTIPLY, MOD, DIVIDE 등 산술 연산을 모두 조합자 기반으로 구현
- 각 연산은 IS_ZERO, PRED, SUCC 등을 재귀적으로 결합해 구성
- 이어서 CONS, FIRST, REST, EMPTY를 정의하며 리스트 구조를 구축
-
MAP, FOLD, RANGE, CONCAT 등 고차 함수형 연산을 모두 조합자 형태로 구현
- 리스트를 문자열로 출력하기 위해 renderList, showLines 함수를 작성
문자와 문자열의 구성
- 지원자는 문자 코드를 1부터 9, 그리고 10단위로 조합자를 이용해 정의
-
CHAR_A부터 CHAR_Z, CHAR_0부터 CHAR_9까지를 모두 수 조합으로 표현
-
ARRAY 함수를 통해 문자열을 리스트로 변환하고, FIZZ, BUZZ, FIZZBUZZ를 생성
-
extractString 함수를 통해 리스트를 실제 문자열로 변환
- 콘솔 출력 결과는 "fizzbuzz"
숫자에서 문자열로의 변환
- 숫자를 자릿수 리스트로 바꾸는 NUMBER_TO_DIGIT_LIST와 이를 문자열로 바꾸는 NUMBER_TO_STRING을 정의
-
DIVIDE, MOD, TEN 등을 이용해 각 자리수를 분리
-
DIGITS_NUMERAL 리스트를 통해 숫자 문자 매핑 수행
- 이 과정을 통해 숫자 → 문자 → 문자열 변환이 완전한 조합자 체계 내에서 가능해짐
FizzBuzz의 완성
-
FIFTEEN, ONE_HUNDRED를 정의하고, MAP과 RANGE를 이용해 1부터 100까지의 리스트를 생성
- 각 숫자에 대해 3, 5, 15의 배수를 판별하여 "Fizz", "Buzz", "FizzBuzz" 또는 숫자 문자열을 출력
-
showLines(extractString)(FIZZBUZZ_RESULT)로 최종 결과를 출력
- Dana는 “이제 만족하냐”고 묻지만, 지원자는 모든 변수 정의를 제거하고 순수 조합자만으로 코드를 재작성
- 결과는 수천 줄에 달하는 S와 K만으로 구성된 거대한 표현식
결말과 의미
- 글은 프로그래밍 언어의 근본적 구성 요소를 탐구하는 동시에, 개발자들이 단순한 문제를 과도하게 복잡하게 만드는 경향을 풍자
- “무(無)보다 적은 것으로 프로그래밍한다”는 제목은 언어의 최소 단위로부터 세계를 재구성하려는 시도를 상징
- 이 작품은 함수형 프로그래밍, 람다 대수, 조합자 논리에 대한 깊은 이해를 유머와 서사로 풀어낸 기술 문학
- 동시에, “FizzBuzz조차 철학적 실험으로 바꾸는 개발자 정신”을 풍자적으로 드러냄