---
title: "Ch1: Flexibility in Nature and in Design"
tags: [source, SDF]
source: "Software Design for Flexibility, Hanson & Sussman (2021)"
chapter: 1
updated: 2026-04-30
---

# Ch1: Flexibility in Nature and in Design

## 핵심 아이디어

소프트웨어는 요구사항 변화에 취약하게 설계되는 경향이 있으며, 이를 극복하기 위한 철학으로 **가산적 프로그래밍(additive programming)**을 제안한다. 기존 코드를 수정하지 않고 추가만으로 새 기능을 구현할 수 있는 시스템 설계 원칙을 생물학적 시스템의 적응성에서 도출한다.

## 주요 개념

### 가산적 프로그래밍 (Additive Programming)

동작하는 프로그램을 수정하지 않고 코드를 *추가*함으로써 새로운 기능을 구현하거나 기존 기능을 새 요구사항에 맞추는 프로그래밍 스타일. 이를 위한 전제조건:

- 프로그램이 어떻게 작동하고 어떻게 사용될지에 대한 가정을 최소화
- just-in-time 결정: 가정을 미리 굳히지 않고 실행 환경에 기반해 결정
- 부분들이 관심사를 명확히 분리하여 의도치 않은 상호작용 최소화

### 아키텍처의 parti 유추

건축의 *parti*(설계 조직 원리)와 유사하게, 프로그램의 추상적 골격(skeleton plan)이 분석·비판·실험 가능한 형태로 존재해야 한다. Java처럼 "served spaces"(실제 동작 코드)와 "servant spaces"(타입 선언, 클래스 선언 등)가 혼재하는 언어보다, Lisp처럼 parti를 드러내는 언어가 유리하다.

### 스마트 파츠 (Smart Parts)

생물학적 세포가 맥락 신호를 읽어 스스로 역할을 결정하듯, 소프트웨어 컴포넌트도 명령적(imperative) 제어 대신 **맥락 반응적(context-responsive)**으로 설계되어야 한다. 이를 통해 변화에 대한 적응이 전체 제어 구조를 수정하지 않고 영향을 받는 부분만의 변경으로 이루어진다.

### 중복성과 퇴화성 (Redundancy and Degeneracy)

- **중복성(redundancy)**: 동일한 기능의 여분 용량 (신장이 두 개인 것처럼)
- **퇴화성(degeneracy)**: 동일한 목적을 달성하는 *서로 다른* 복수의 메커니즘

퇴화성은 단순 중복성보다 강력하다. 한 방식이 실패해도 다른 방식이 작동하며, 서로 다른 메커니즘이므로 동일한 버그를 공유하지 않는다. 부분 정보들을 결합하면 개별 결과보다 더 정확한 결과를 얻을 수 있다 (예: 항법 시스템의 다중 위치 추정 결합).

### 탐색적 행동 (Exploratory Behavior)

생성-검증(generate-and-test) 메커니즘: 생성기는 제안을 내놓고, 검증기는 수락 또는 거부한다. 두 부분이 독립적으로 발전 가능하므로 한쪽의 변화가 다른 쪽의 변화를 요구하지 않는다. 백트래킹이 이 메커니즘의 계산적 구현이며, Chapter 4(패턴 매칭), Chapter 5(인터프리터의 amb), Chapter 7(의존성 지향 백트래킹)에서 순차적으로 발전시킨다.

### 유연성의 비용

유연성은 공간, 계산 시간, 프로그래머 시간에서 일정한 오버헤드를 수반한다. 그러나 소프트웨어의 주된 비용은 프로그래머가 생애주기 동안 소비하는 시간이다. 적응성이 높은 설계는 재작성·리팩토링 비용을 줄이므로 장기적으로 비용이 가산적(additive)이 된다.

### 정확성 요구의 문제

모든 것을 증명 가능하게 만들라는 규율은 오히려 시스템을 취약하게 만든다. 일반적인 메커니즘의 일반적 속성을 증명하기는 특수 메커니즘의 특수 속성을 증명하기보다 어렵기 때문에, 증명 요구는 부품을 가능한 한 특수하게 만들도록 유도한다. 특수화된 부품의 결합은 변화의 여지가 없어 취약하다.

## 핵심 인용

> "One should not have to modify a working program. One should be able to add to it to implement new functionality or to adjust old functions for new requirements. We call this *additive programming*."

> "Be conservative in what you do, be liberal in what you accept from others." (Postel's Law, RFC760)

> "In order for additive programming to be possible, it is necessary to minimize the assumptions about how a program works and how it will be used."

## 관련 개념

- [[SDF-ch2-dsl]] — 가산적 프로그래밍의 첫 번째 구체적 도구: 컴비네이터와 DSL
- [[SDF-ch3-generic-procedures]] — 제네릭 프로시저를 통한 기능 확장
- [[SDF-ch6-layering]] — 레이어링으로 기존 코드를 수정 없이 메타데이터 추가
- [[SDF-ch7-propagation]] — 퇴화성과 부분 정보 결합의 완성형
- [[SDF-overview]] — 책 전체 구조
