feat: wiki/concepts/ 핵심 개념 페이지 8개 생성

SDF 챕터들에서 추출한 핵심 개념:
- additive-programming: 가산적 프로그래밍 (전체 관통 테마)
- generic-procedures: 제네릭 프로시저 (Ch3, Ch5, Ch6)
- combinators: 컴비네이터 (Ch2~Ch5)
- partial-information: 부분 정보 (Ch1, Ch4, Ch6, Ch7)
- degeneracy: 퇴화성 (Ch1, Ch7)
- layered-data: 레이어드 데이터 + 의존성 추적 (Ch2, Ch3, Ch6, Ch7)
- propagation: 전파 모델 (Ch1, Ch5, Ch6, Ch7)
- domain-specific-language: DSL (Ch2~Ch5)

wiki/index.md Concepts 섹션 등록, wiki/log.md 기록

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-30 14:55:04 +09:00
parent ea46da91db
commit f868de1ce7
10 changed files with 901 additions and 1 deletions

View File

@@ -0,0 +1,132 @@
---
title: 도메인 특화 언어 (DSL)
tags: [concept, SDF]
sources: [SDF-ch2-dsl, SDF-ch3-generic-procedures, SDF-ch4-pattern-matching, SDF-ch5-evaluation]
updated: 2026-04-30
---
# 도메인 특화 언어 (DSL)
## 한 줄 정의
문제 도메인의 개념과 관계를 직접 반영하는 어휘와 구조를 가진 언어로, 해당 도메인의 문제를 그 언어로 자연스럽게 표현할 수 있게 하여 도메인 전문가와 프로그래머 사이의 간격을 줄이고 가산적 확장을 가능하게 한다.
## 핵심 내용
### DSL의 스펙트럼
SDF에서 DSL은 단일한 기법이 아니라 구현 깊이에 따른 스펙트럼이다:
**1단계: 컴비네이터 기반 임베디드 DSL (Ch2)**
- 호스트 언어(Scheme) 함수들을 컴비네이터로 조합
- 별도의 파서 없음. 호스트 언어의 문법을 그대로 사용
- 예: 정규표현식 컴비네이터, 함수 컴비네이터
**2단계: 제네릭 프로시저 기반 도메인 언어 (Ch3)**
- 도메인의 연산(더하기, 곱하기)이 제네릭 프로시저
- 새 타입이 도입될 때마다 핸들러를 추가해 도메인을 확장
- 예: 숫자 → 기호 → 함수 → 미분 객체로 확장되는 산술
**3단계: 패턴 기반 규칙 언어 (Ch4)**
- 데이터 변환을 패턴+귀결 규칙으로 표현
- `rule-simplifier`가 고정점까지 규칙들을 자동 적용
- 예: 대수 단순화 규칙들, 체스 규칙
**4단계: 완전한 인터프리터 (Ch5)**
- 새 언어를 완전히 정의: 구문, 의미, 실행 모델
- 가장 강력하지만 가장 많은 투자가 필요
- 예: lazy eval, amb를 포함한 Scheme 인터프리터
### 왜 DSL인가
> "One of the best ways to attack a problem is to make up a domain-specific language in which the solution is easily expressed."
> "Programmers should know how to escape the confines of whatever programming language they must use by making an interpreter for a language that is more appropriate for expressing the solution."
범용 언어로 도메인 문제를 풀면 두 가지 불편이 생긴다:
1. **개념의 직접성 부재**: 도메인 개념을 언어 구조에 억지로 매핑해야 함
2. **가산성 어려움**: 새 개념이 추가될 때 기존 코드의 여러 곳을 수정해야 함
DSL은 도메인 개념이 언어의 일급 시민이 되므로 두 문제가 모두 해결된다.
### 도메인 모델 분리: 체커 게임 사례
Ch2의 체커 게임 심판 구현은 DSL 설계의 좋은 교육 사례다:
**1단계 — 모놀리식**: 킹(king), 점프(jump) 같은 체커 특화 개념이 코드 전체에 분산됨. 새 규칙을 추가하려면 여러 곳을 수정해야 함.
**2단계 — 도메인 모델 분리**:
- `partial-move(pmove)` 추상화: 이동 경로를 표현하는 도메인 객체
- **룰 익스큐티브(rule executive)**: 제어 구조를 규칙에서 분리
- **진화 규칙(evolution rules)**: pmove를 새 pmove들로 변환
- **집합 규칙(aggregate rules)**: 완료된 pmove 집합에 작용
- 각 체커 규칙이 단일 프로시저로 표현됨
이제 새 규칙(예: "룰 변형" 게임)을 추가하는 것은 새 프로시저를 등록하는 것이다. 기존 규칙 프로시저들은 그대로다.
도메인 모델 = 도메인 언어의 프리미티브 + 조합 수단 + 추상화 수단.
### 정규표현식: DSL의 나쁜 예
> "Regular expressions are a beautiful example of how *not* to build a system."
전통 정규표현식의 문제:
- 컨텍스트 의존성: `^`, `.`, `*`이 위치에 따라 의미가 다름
- 조합 불가능: `(abc)|(def)` 조각은 독립적으로 재사용할 수 없음
- 가독성: 복잡한 패턴은 해독이 불가능
컴비네이터 기반 대안은 각 부품이 독립적이고, 조합이 안전하며, 의미가 명확하다. 성능이 약간 낮을 수 있지만, 컴파일러로 POSIX BRE로 변환하면 해결된다.
### 인터프리터: DSL의 궁극적 형태
인터프리터를 만드는 것은 새 언어를 만드는 것이다. Ch5의 인터프리터는 가산적으로 확장 가능하다:
- `g:eval`을 제네릭 프로시저로 구현: 새 표현식 타입은 새 핸들러 추가
- 분석/실행 분리: 새 평가 전략(lazy, amb)은 실행 단계만 수정
- lazy eval: 매개변수 선언으로 평가 전략 지정 → 선언적 DSL
```scheme
;; 언어 확장: lazy 평가 지원 추가
(lambda ((lazy x) y) ; x는 필요할 때만 평가
(if (zero? y) 0 (* x y)))
```
이 확장은 인터프리터의 핸들러를 추가하는 것만으로 이루어진다.
### 배선도 언어 (Ch7)
전파 모델의 배선도 언어는 또 다른 형태의 DSL이다. 제약(constraint)을 언어의 기본 단위로 삼는 선언적 언어다:
```scheme
;; 곱셈 제약: 세 변수 중 둘을 알면 나머지를 계산
(c:* a b c)
;; 삼각함수 제약
(c:tan angle ratio)
```
이 언어에서 "프로그램"은 제약들의 네트워크다. 제어 흐름이 없다.
## SDF에서의 등장
- [[SDF-ch2-dsl]]: 핵심 챕터. 컴비네이터 기반 임베디드 DSL, 정규표현식 DSL, 래퍼, 체커 도메인 모델
- [[SDF-ch3-generic-procedures]]: 제네릭 산술이 도메인별 확장을 지원하는 DSL의 기반 인프라
- [[SDF-ch4-pattern-matching]]: 패턴+규칙 시스템이 변환 DSL. 대수 단순화 규칙들이 대수 DSL
- [[SDF-ch5-evaluation]]: 완전한 인터프리터 구현. lazy eval과 amb를 DSL 확장으로 추가하는 과정
## 실천 시 주의점
**DSL의 복잡성 비용**: DSL을 만들면 DSL 자체를 배워야 하는 학습 비용이 생긴다. "이 DSL을 쓰는 사람이 나 혼자인가?"를 먼저 물어야 한다. 팀의 크기와 도메인의 복잡성이 DSL 투자를 정당화해야 한다.
**임베디드 vs 독립 DSL**: 임베디드 DSL(EDSL)은 호스트 언어의 도구를 모두 쓸 수 있지만, 호스트 언어의 문법 제약을 받는다. 독립 DSL은 문법 자유도가 높지만 파서·인터프리터 구현 비용이 크다. 대부분의 경우 EDSL이 더 실용적이다.
**도메인 모델의 안정성**: DSL은 도메인 모델이 안정적일 때 투자할 가치가 있다. 도메인 모델이 자주 변하면 DSL 자체를 수정하는 비용이 DSL이 주는 이점을 상회한다.
**에러 메시지 품질**: 사용자가 DSL을 잘못 사용했을 때 의미 있는 에러 메시지를 제공해야 한다. 호스트 언어의 에러가 DSL 사용자에게 노출되면 "내부 구현"이 드러나 추상화가 새는 것이다.
## 관련 개념
- [[additive-programming]] — DSL은 가산적 확장이 자연스러운 언어 레벨 추상화
- [[combinators]] — 임베디드 DSL의 핵심 구현 메커니즘
- [[generic-procedures]] — 제네릭 프로시저로 도메인 연산을 확장 가능하게 구현
- [[propagation]] — 배선도 언어 자체가 제약 기반 DSL