--- 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 = () => (