
⚡ 한 줄 요약: SICP 2.4.3의 '데이터 지향 프로그래밍(put/get 디스패치 표)'은 하스켈에선 타입클래스로 거의 그대로 옮겨지지만, 런타임 표가 아닌 컴파일타임·타입안전 디스패치라는 점이 핵심 차이다.
📑 목차
📌 무슨 일인가
해커뉴스에 SICP(계산기 프로그램의 구조와 해석) 2장 2.4.3절 "데이터 지향 프로그래밍(Data-directed programming)"을 하스켈로 다시 구현한 글이 올라와 토론이 붙었습니다.
원문은 Scheme으로 쓰인 SICP의 제네릭 연산 예제를 하스켈로 옮기면서, SICP의 핵심 장치인 '연산×타입 → 함수' 조회 테이블이 하스켈에선 어떤 언어 기능과 대응하는지를 짚습니다.
결론부터 말하면, 그 자리를 타입클래스(typeclass)가 메꿉니다.
다만 성격이 다릅니다.
🧩 데이터 지향 프로그래밍이 뭐였나
SICP는 "여러 표현을 가진 데이터에 대해 하나의 제네릭 연산을 만드는" 방법을 세 가지로 정리합니다.
- 타입 검사 분기(dispatch on type): 연산마다
if 직교좌표면… else 극좌표면…을 넣는 방식. 표현이 하나 늘 때마다 모든 연산을 다 고쳐야 합니다. - 메시지 전달(message passing): 데이터 자체가 연산을 들고 다니는 방식.
- 데이터 지향(data-directed):
(연산, 타입태그) → 프로시저를 담는 표(table)를 만들고,put으로 등록·get으로 꺼내 실행. 새 표현을 추가할 땐 표에 열 하나만 더 붙이면 되고 기존 코드는 손대지 않습니다.
이 마지막 방식의 미덕이 바로 가산성(additivity) — "기존 코드 수정 없이 확장"입니다.
💡 개발자에게 주는 의미
여기서 눈치챈 분도 있을 겁니다.
이건 사실 그 유명한 Expression Problem(표현 문제)의 절반입니다.
필립 와들러가 정리한 이 문제는 "새 타입 추가와 새 연산 추가를 둘 다, 기존 코드 수정 없이, 타입 안전하게 할 수 있는가?"를 묻습니다.
- SICP의 put/get 표는 런타임 딕셔너리입니다. 유연하지만 타입 태그가 틀리면 실행 중에 터지고, 컴파일러가 누락을 잡아주지 못합니다.
- 하스켈 타입클래스는 같은 "연산×타입 → 구현" 매핑을 컴파일타임에 해결합니다. 인스턴스가 없으면 아예 빌드가 실패하므로, SICP 표의 "빈 칸" 버그가 원천 차단됩니다.
즉 하스켈은 SICP가 손으로 굴리던 디스패치 표를 언어 기능으로 승격시킨 셈입니다.
대신 방향이 갈립니다.
타입클래스는 새 타입 추가(인스턴스 하나)는 쉽지만, 새 연산 추가는 클래스 메서드를 건드려야 합니다.
반대로 대수적 데이터 타입(합 타입)에 패턴 매칭하는 방식은 새 연산 추가는 쉬운데 새 타입 추가가 번거롭습니다.
무엇을 자주 확장할지에 따라 골라야 합니다.
🛠 실무 적용 포인트
가산성을 코드로 체감해 봅시다.
새 도형을 추가할 때 기존 코드가 한 줄도 안 바뀌는 게 핵심입니다.
-- 제네릭 연산을 타입클래스로 선언 (SICP의 'get' 자리)
class Shape a where
area :: a -> Double
data Circle = Circle Double
data Square = Square Double
-- 각 타입의 구현 = SICP의 'put' (표에 칸 채우기)
instance Shape Circle where
area (Circle r) = pi * r * r
instance Shape Square where
area (Square s) = s * s
-- ▼ 새 표현 추가: 기존 코드 수정 0, 인스턴스만 추가
data Triangle = Triangle Double Double
instance Shape Triangle where
area (Triangle b h) = b * h / 2
반대로 "타입은 고정, 연산을 자주 늘린다"면 합 타입 + 패턴 매칭이 낫습니다.
data Shape = Circle Double | Square Double
area :: Shape -> Double -- 연산 추가는 새 함수만 쓰면 끝
area (Circle r) = pi * r * r
area (Square s) = s * s
perimeter :: Shape -> Double -- 기존 코드 수정 없이 연산 확장
perimeter (Circle r) = 2 * pi * r
perimeter (Square s) = 4 * s
정확도 참고: 하스켈에서 표현·구현을 완전히 분리하고 런타임 다형을 흉내 내려면 class에 더해 존재 타입(ExistentialQuantification)이나 GADTs가 필요할 수 있습니다.
세부 확장 문법은 GHC 공식 문서 확인을 권장합니다.
✅ 체크포인트
- 제네릭 연산 설계 시, "타입을 자주 늘리나 vs 연산을 자주 늘리나" 먼저 판단하라. 전자는 타입클래스, 후자는 합 타입+패턴 매칭.
- SICP의 put/get 표가 익숙하다면, 그 정신적 모델을 타입클래스 = 컴파일타임 디스패치 표로 바꿔 읽으면 하스켈이 훨씬 빨리 이해된다.
- 런타임 문자열 태그로 디스패치하는 코드(자바스크립트
switch(type)등)를 쓰고 있다면, 언어의 다형 기능으로 옮겨 누락을 컴파일러가 잡게 만들 여지가 있는지 점검해 보라.
📚 참고(출처)
- Entropic Thoughts — Data-directed programming in Haskell (SICP 2.4.3)
- MIT — Structure and Interpretation of Computer Programs, §2.4.3 Data-Directed Programming and Additivity
📊 오늘의 개발 트렌드 (자동 집계)
GitHub·Hacker News·Hugging Face·App Store·Cloudflare Radar에서 매일 자동으로 모은 개발 트렌드입니다. (2026-07-14 18:43 기준)
🐙 GitHub 급상승
- OpenCut-app/OpenCut (+1,229★/일) — The open-source CapCut alternative
- Dicklesworthstone/destructive_command_guard (+1,295★/일) — The Destructive Command Guard (dcg) is for blocking dangerous git and
- HKUDS/Vibe-Trading (+1,153★/일) — "Vibe-Trading: Your Personal Trading Agent"
📰 Hacker News 화제
- Building and shipping Mac and iOS apps without opening Xcode (468p·203💬)
- Japan develops a method to recover up to 90% of lithium from used EV batteries (462p·114💬)
- The git history command (291p·168💬)
🤗 Hugging Face 트렌딩 모델
- empero-ai/Qwythos-9B-Claude-Mythos-5-1M-GGUF (2,006,265 DL·2105♥)
- tencent/Hy3 (10,406 DL·763♥)
💰 App Store 매출 TOP (한국)
- ChatGPT — OpenAI OpCo, LLC
- YouTube — Google
- 카카오톡 KakaoTalk — Daum Corp.
🌐 가장 많이 방문되는 웹 (Cloudflare Radar)
- google.com (#1) · Search Engines
- googleapis.com (#2) · Information Technology
- gstatic.com (#3) · Content Servers
'개발 인사이트' 카테고리의 다른 글
| AI가 못 지우는 울타리 (0) | 2026.07.18 |
|---|---|
| BIOS만 있는 PC, OS 없이 부팅하기 (0) | 2026.07.13 |
| 가로등 밑에는 버그가 없다 (0) | 2026.07.11 |
| AI는 개발자를 죽이지 않는다, 자비스처럼 '아이언맨'으로 만든다 (0) | 2026.07.02 |
| AI가 천재라는 말, 절반은 거짓말입니다 (0) | 2026.07.02 |