타입 기반 설계 전략 코드의 운명을 런타임에서 컴파일 타임으로

궁금하면 500원·2026년 1월 8일

MSA&아키텍처

목록 보기
46/46

이미지 출처 제미나이

1. 컴파일 타임 흐름제어

1.1 값 분기 vs 타입 분기

전통적인 흐름 제어가 실행 시점(Runtime)의 데이터 값에 의존했다면, 현대적 설계는 이를 구조(Type)의 영역으로 격상시킵니다.

구분값 기반 분기 (런타임)타입 기반 분기 (컴파일 타임)
핵심 기제if-else, switch, 상태 코드, 플래그합타입(Sum Type), match/when, 대수타입
흐름의 성격코드 곳곳에 흩어진 파편화된 경로타입 정의에 의해 닫힌 경로 공간
강제성누락 시 런타임 오류 혹은 논리적 미아 발생누락 시 컴파일 오류 (Exhaustive Check)
추적성실행 경로 예측을 위한 조건문 전수 조사타입 정의 자체가 흐름의 지도 역할

1.2 타입은 흐름의 지도 설계 원칙

  • 합타입: 발생 가능한 모든 경로의 선택지를 정적으로 열거합니다.
  • 곱타입: 특정 경로 내에서 반드시 함께 존재해야 하는 유효 데이터를 정의합니다.
  • 전이의 위임: match/when은 단순한 분기문이 아니라, 분기 결과를 다음 단계의 으로 변환하여 전달하는 "전이 장치"입니다.
  • 설계 순서: 흐름을 먼저 고민하고 타입에 맞추는 것이 아니라, match에서 처리될 수밖에 없는 구조로 타입을 먼저 구성합니다.

2. 상태와 사상의 분리

소프트웨어의 복잡성은 '시간'에 따라 변하는 것과 변하지 않는 것을 구분하지 못할 때 발생합니다.

2.1 식별자와 시간의 결합 상태

  • 값(Value): 3, "Hello"와 같이 시공간을 초월하여 변하지 않는 데이터.
  • 상태(State): 특정 식별자(ID)가 특정 시점에 어떤 값을 가리키고 있는가에 대한 결합 정보.
  • 엔티티 설계: 상태 홀더는 식별자를 고정하고 내부의 VO 스냅샷을 교체하는 방식으로 정의됩니다.

    Entity<ID, VO>: ID는 변하지 않으며, VO는 전이에 의해 교체됩니다.

2.2 순수 변환의 영역 사상(Mapping)

  • 정의: 값이 다른 값으로 변하는 과정이며, 식별자가 필요 없습니다.
  • 특징: 입력()이 있으면 결과()가 나오는 전 과정이 투명해야 합니다.
  • 문제 해결: 사상의 연속을 통해 최종 결과값을 얻어내는 과정으로 정의합니다.

2.3 상태 전이 vs 값 사상의 협력

전략상태 전이값 사상
메커니즘식별자 내부의 값을 교체주어진 값을 변환하여 새 값을 반환
비정상 처리값 교체 거부 혹은 예외 발생특수한 타입(Option, Either) 반환
철학객체 간의 메시지 협력함수 간의 합성 및 사상

3. 사상과 부수효과 처리

3.1 전함수의 지향

사상이 성공하려면 모든 입력에 대해 반드시 결과가 보장되어야 합니다.
부수효과가 발생하는 순간 함수는 전함수가 아니게 되며, 합성이 불가능해집니다.

3.2 현실의 부수효과 처리 기법

A. 기억의 관리

  • 클로저(Closure): 사상의 결과물에 환경을 포획하여 전달.
  • 지연 연산(Lazy/Thunk): 연산 자체를 캡슐화하여 실제 값이 필요한 시점까지 실행을 유예.

B. 예외의 타입화

  • 메타타입(Meta-Type): 구상 타입을 감싸는 래퍼(Either, Option, Result).
  • 대수적 처리: 처리 로직을 타입 내부에 가두어 map, flatMap 등을 통해 일관된 시그니처로 관리합니다.
// 예시: Either를 이용한 대수적 부수효과 처리
sealed interface Either<out L, out R> {
    data class Left<out L>(val error: L) : Either<L, Nothing>
    data class Right<out R>(val result: R) : Either<Nothing, R>

    // 사상을 유지하며 안전하게 흐름을 이어감 (전함수성 유지)
    fun <T> map(block: (R) -> T): Either<L, T> = when (this) {
        is Left -> this
        is Right -> Right(block(result))
    }
}

4. 흐름은 타입이 통제하고, 논리는 함수가 수행한다

가장 이상적인 설계는 "논리는 순수한 함수에 두고, 그 함수들이 연결되는 흐름은 타입 시스템이 강제하는 구조"입니다.

  1. 흐름의 박제: 모든 분기를 타입으로 정의하여 match로 강제합니다.
  2. 전이의 폐쇄: 상태 변경은 정해진 전이 함수를 통해서만 일어납니다.
  3. 사상의 투명: 부수효과는 메타타입이나 지연 실행을 통해 값의 영역으로 끌어올립니다.

이러한 접근을 통해 개발자는 "발견되는 흐름"을 뒤쫓는 것이 아니라, "보장된 흐름" 위에서 안전하게 로직을 전개할 수 있습니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글