--- id: wiki-2026-0508-bottom-up-approach title: Bottom Up Approach category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Bottom-Up Design, Bottom-Up vs Top-Down, Composition-First Design] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [design, methodology, top-down, bottom-up, architecture] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Polyglot framework: Methodology --- # Bottom Up Approach ## 매 한 줄 > **"매 bottom-up = 매 작은 building block 부터 만들고 합쳐 system 으로 키우는 composition-first 접근."**. 매 top-down 이 spec → decompose 인 반면, bottom-up 은 primitive → compose. 매 2026 modern 실무는 hybrid (meet-in-the-middle) — 매 spike/prototype 은 bottom-up, architecture 는 top-down, 매 LLM-driven 합성에서 bottom-up 의 compositional reasoning 이 다시 부상. ## 매 핵심 ### 매 distinction - **Top-down**: 매 high-level spec → subsystem → module → function. 매 known-domain 적합. - **Bottom-up**: 매 primitive utility → combinator → application. 매 unknown-domain / discovery 적합. - **Meet-in-the-middle**: 매 양쪽 동시 → 중간에서 만남. - **Outside-in (TDD)**: 매 acceptance test → unit — 매 top-down 변형. ### 매 strengths - **Reusability**: 매 primitive 가 여러 system 에 공통. - **Testability**: 매 작은 unit 부터 100% covered. - **Discoverability**: 매 unknown territory 에서 "뭐가 가능한지" 발견. - **Compositional**: 매 functional programming, Lisp, Forth 의 핵심. ### 매 weaknesses - **No big picture**: 매 individual unit 우수해도 system 일관성 부재 가능. - **YAGNI risk**: 매 안 쓰일 primitive 까지 만들 수 있음. - **Integration debt**: 매 끝에 가서야 합쳐지는 surprise. ### 매 응용 1. **Functional libraries**: 매 Lodash, Ramda — combinator 가 primitive. 2. **Forth / Concatenative langs**: 매 word 정의 후 합성. 3. **Embedded firmware**: 매 driver → HAL → app. 4. **ML pipeline**: 매 ops → layers → model. 5. **Spike / discovery prototype**: 매 architecture 모르는 phase. ## 💻 패턴 ### Functional combinator (bottom-up) ```haskell -- primitives add1 :: Int -> Int add1 x = x + 1 double :: Int -> Int double x = x * 2 -- composition (no top-level spec needed) addThenDouble :: Int -> Int addThenDouble = double . add1 -- application emerges by composing process :: [Int] -> [Int] process = map (double . add1) . filter (> 0) ``` ### Lisp — define primitives, then compose ```lisp (defun double (x) (* x 2)) (defun increment (x) (+ x 1)) (defun process (xs) (mapcar (lambda (x) (double (increment x))) (remove-if-not #'plusp xs))) ``` ### Embedded — HAL up ```c // 1. register-level primitive void gpio_set_high(uint32_t pin) { GPIO_BSRR = 1u << pin; } // 2. driver void led_on(led_t led) { gpio_set_high(led.pin); } // 3. application void heartbeat(void) { while (1) { led_on(STATUS_LED); delay_ms(500); led_off(STATUS_LED); delay_ms(500); } } ``` ### React UI — primitive components up ```tsx // 1. atoms const Button = ({ children, ...props }) => ; const Input = ({ ...props }) => ; // 2. molecules const SearchBox = () => (
); // 3. page (emerges) const HomePage = () =>
; ``` ### Spike-driven discovery ```python # Day 1 — bottom-up exploration before architecture exists def parse_log_line(s): ... # primitive def filter_errors(lines): ... # combinator def aggregate_by_minute(lines): ... def render_chart(buckets): ... # After 2 days you SEE the pipeline → THEN write architecture doc ``` ### LLM compositional planning (modern bottom-up) ```python # Claude tool-use bottom-up: define small tools, let model compose tools = [ {"name": "search_db", "description": "..."}, {"name": "render_chart", "description": "..."}, {"name": "send_email", "description": "..."}, ] # Model receives high-level task and composes a plan from primitives client.messages.create( model="claude-opus-4-7", tools=tools, messages=[{"role": "user", "content": "Send a weekly sales summary"}], ) ``` ### Forth — concatenative composition ```forth : SQUARE DUP * ; \ primitive : CUBE DUP SQUARE * ; \ compose : AREA SQUARE 3.14159 * ; \ compose with literal ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Domain unknown / spike | Bottom-up | | Spec frozen, deadline | Top-down | | Reusable library | Bottom-up | | End-to-end product | Hybrid (meet in middle) | | TDD acceptance | Outside-in (top-down variant) | | LLM tool-using agent | Bottom-up primitives, top-down task | **기본값**: hybrid — 매 architecture skeleton (top-down) + 매 primitive layer (bottom-up) → 매 meet middle. ## 🔗 Graph - 응용: [[Functional_Programming]] · [[Atomic_Design]] - Adjacent: [[Composition]] · [[YAGNI]] ## 🤖 LLM 활용 **언제**: unknown domain spike, library design, primitive 조합 탐색, agentic tool composition. **언제 X**: regulated/safety system 의 spec-driven part — 매 top-down 우선. ## ❌ 안티패턴 - **Pure bottom-up without integration plan**: 매 primitive 100개 + 통합 안 됨 = 0 가치. - **Premature primitives**: 매 안 쓰일 utility 양산 (YAGNI 위반). - **Bottom-up for legally-specified systems**: 매 spec drift → compliance fail. - **Skipping integration tests**: 매 unit 모두 green 인데 system fail. ## 🧪 검증 / 중복 - Verified (Abelson&Sussman SICP 1985, Forth dictionary docs, "Out of the Tar Pit" 2006). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — bottom-up vs top-down, composition patterns, hybrid default |