feat: SDF wiki 컴파일 — 챕터별 한국어 소스 페이지 8개
Software Design for Flexibility (Hanson & Sussman 2021) 전문을 wiki/sources/ 아래 챕터별 한국어 wiki 페이지로 컴파일 - SDF-overview: 전체 개요, 챕터 관계도, 공통 테마 - SDF-ch1: 가산적 프로그래밍 철학, 퇴화성, 유연성 비용 - SDF-ch2: 컴비네이터, DSL, 래퍼, 도메인 모델 - SDF-ch3: 제네릭 프로시저, 자동 미분, 트라이 디스패치 - SDF-ch4: 패턴 매칭, 항 재작성, 단일화, 타입 추론 - SDF-ch5: eval/apply, lazy eval, amb, call/cc - SDF-ch6: 레이어드 데이텀/프로시저, 단위 산술, 의존성 추적 - SDF-ch7: 전파 모델, 부분 정보 결합, 의존성 지향 백트래킹 wiki/index.md Sources 섹션 등록, wiki/log.md 기록 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
126
wiki/sources/SDF-ch2-dsl.md
Normal file
126
wiki/sources/SDF-ch2-dsl.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: "Ch2: Domain-Specific Languages"
|
||||
tags: [source, SDF]
|
||||
source: "Software Design for Flexibility, Hanson & Sussman (2021)"
|
||||
chapter: 2
|
||||
updated: 2026-04-30
|
||||
---
|
||||
|
||||
# Ch2: Domain-Specific Languages
|
||||
|
||||
## 핵심 아이디어
|
||||
|
||||
유연한 시스템을 구축하는 핵심 전략은 도메인 특화 언어(DSL)를 만드는 것이다. DSL은 문제 도메인의 개념 구조를 직접 반영하는 언어로, **컴비네이터 시스템**, **래퍼**, **도메인 모델 추상화** 세 가지 기법으로 구성된다. 모든 조합이 유효한 프로그램을 만들어내는 믹스앤매치(mix-and-match) 부품 체계가 핵심이다.
|
||||
|
||||
## 주요 개념
|
||||
|
||||
### 2.1 컴비네이터 시스템 (Combinator Systems)
|
||||
|
||||
**컴비네이터 언어**의 정의: 원시 부품(primitives)과 조합 수단(combinators)의 집합으로, 조합의 인터페이스 명세가 원시 부품의 인터페이스 명세와 동일한 것.
|
||||
|
||||
핵심 성질:
|
||||
- 임의의 믹스앤매치 가능
|
||||
- 어떤 조합도 유효한 프로그램 생성 (법적으로 유효, legally correct)
|
||||
- 부품의 동작은 컨텍스트에 독립적
|
||||
- 새 부품이나 컴비네이터 추가가 기존 프로그램에 영향 없음
|
||||
|
||||
**기본 함수 컴비네이터들:**
|
||||
|
||||
```scheme
|
||||
;; compose: f ∘ g
|
||||
(define (compose f g)
|
||||
(define (the-composition . args)
|
||||
(call-with-values (lambda () (apply g args)) f))
|
||||
(restrict-arity the-composition (get-arity g)))
|
||||
|
||||
;; parallel-combine: h(f(args), g(args))
|
||||
(define (parallel-combine h f g)
|
||||
(define (the-combination . args)
|
||||
(h (apply f args) (apply g args)))
|
||||
the-combination)
|
||||
|
||||
;; spread-combine: h(f(첫 n개 인수), g(나머지 인수))
|
||||
(define (spread-combine h f g)
|
||||
(compose h (spread-apply f g)))
|
||||
```
|
||||
|
||||
**기타 유용한 컴비네이터:**
|
||||
- `discard-argument i` — i번째 인수를 무시하는 함수 생성
|
||||
- `curry-argument i` — i번째 인수를 고정하는 커링
|
||||
- `permute-arguments` — 인수 순서 재배열
|
||||
|
||||
**아리티(Arity) 관리**: 컴비네이터가 올바르게 작동하려면 각 함수의 인수 개수를 추적해야 한다. `restrict-arity`와 `get-arity`로 함수에 아리티를 "스티키 노트"처럼 첨부한다 (해시 테이블 사용).
|
||||
|
||||
### 2.2 정규 표현식 DSL
|
||||
|
||||
정규 표현식은 DSL의 **나쁜 예시**: 조각들이 독립적으로 조합되지 않으며, 컨텍스트에 따라 의미가 달라진다. 이를 개선하기 위해 컴비네이터 기반 DSL을 만들고 POSIX BRE 문법으로 컴파일한다.
|
||||
|
||||
```scheme
|
||||
;; 기본 패턴 프리미티브
|
||||
(r:dot) ; 임의의 문자
|
||||
(r:bol) ; 줄 시작
|
||||
(r:eol) ; 줄 끝
|
||||
(r:quote string) ; 문자열 그대로 매칭
|
||||
(r:char-from string) ; 집합에서 한 문자
|
||||
|
||||
;; 컴비네이터
|
||||
(r:seq pat ...) ; 순서대로 매칭
|
||||
(r:alt pat ...) ; 하나라도 매칭
|
||||
(r:repeat min max pat) ; 반복 매칭
|
||||
```
|
||||
|
||||
교훈: 조합 가능한 부품과 컴비네이터로 만든 DSL이 전통적 정규 표현식보다 단순하고 견고하다.
|
||||
|
||||
### 2.3 래퍼 (Wrappers)
|
||||
|
||||
기존 프로그램을 재작성하지 않고 **감싸서(wrapping)** 새 컨텍스트에서 사용하는 전략.
|
||||
|
||||
단위 변환 예시: `gas-law-volume`(SI 단위 기준)을 화씨/PSI/인치로 사용하고 싶을 때, 프로시저 자체를 수정하지 않고 `unit-specializer`로 래퍼를 생성:
|
||||
|
||||
```scheme
|
||||
(define make-specialized-gas-law-volume
|
||||
(unit-specializer gas-law-volume
|
||||
'(expt meter 3) ; 출력 단위
|
||||
'(/ newton (expt meter 2)) ; 압력
|
||||
'kelvin ; 온도
|
||||
'mole)) ; 양
|
||||
|
||||
(define conventional-gas-law-volume
|
||||
(make-specialized-gas-law-volume
|
||||
'(expt inch 3) '(/ pound (expt inch 2))
|
||||
'fahrenheit 'mole))
|
||||
```
|
||||
|
||||
원칙: 기본 프로그램은 단순하고 일반적으로 유지하고, 특수화는 래퍼로 감싸서 수행. 세 부분(기본 프로그램, 래퍼, 단위 특수화기)이 느슨하게 결합되어 각각 독립적으로 일반화 가능.
|
||||
|
||||
### 2.4 도메인 추상화 (Abstracting a Domain)
|
||||
|
||||
체커 게임 심판 구현을 통해 DSL 레이어 구축 과정을 보여준다.
|
||||
|
||||
**1단계 — 모놀리식 구현**: 도메인 모델이 체커 특화적이며, 규칙이 코드 전체에 분산됨.
|
||||
|
||||
**2단계 — 도메인 모델 분리**:
|
||||
- 게임 특화 요소(킹, 점프 등)를 추상적 타입(심볼 타입, change 플래그)으로 교체
|
||||
- `partial-move(pmove)` 추상화로 이동 경로 표현
|
||||
- **룰 익스큐티브(rule executive)**: 제어 구조를 규칙에서 분리
|
||||
- **진화 규칙(evolution rules)**: pmove를 새 pmove들로 변환
|
||||
- **집합 규칙(aggregate rules)**: 완료된 pmove 집합에 작용
|
||||
- 각 체커 규칙이 단일 프로시저로 표현됨
|
||||
|
||||
도메인 모델 = 도메인 언어의 프리미티브 + 조합 수단 + 추상화 수단.
|
||||
|
||||
## 핵심 인용
|
||||
|
||||
> "A *system of combinators* is a set of primitive parts and a set of means of combining parts such that the interface specifications of the combinations are the same as those of the primitives."
|
||||
|
||||
> "Rather than rewriting a program to adapt it to a new purpose, it's preferable to start with a simple and general base program and wrap it to specialize it for a particular purpose."
|
||||
|
||||
> "The moral of this story is that regular expressions are a beautiful example of how *not* to build a system. Using composable parts and combinators to make new parts by combining others leads to simpler and more robust implementations."
|
||||
|
||||
## 관련 개념
|
||||
|
||||
- [[SDF-ch1-flexibility]] — 가산적 프로그래밍의 철학적 기반
|
||||
- [[SDF-ch3-generic-procedures]] — 컴비네이터 한계를 극복하는 제네릭 프로시저
|
||||
- [[SDF-ch4-pattern-matching]] — 패턴 매칭 컴비네이터
|
||||
- [[SDF-ch5-evaluation]] — 인터프리터로 언어에 완전한 의미 부여
|
||||
- [[SDF-ch6-layering]] — 래퍼 개념의 확장인 레이어링
|
||||
Reference in New Issue
Block a user