본문으로 건너뛰기

#1. 듣기를 멈추자!

calendar-ui

frp-diagram

🧭 목표

  • FRP의 정의
  • 이벤트가 문제가 되는 상황
  • FRP의 목표와 해결 방식
  • FRP의 장점
  • 시스템 작동 원리
  • 사고 방식 전환

📌 FRP란?

  • 리스너 기반 구조의 대안
  • 코드가 간단, 명확, 견고해짐
  • FP와 관련은 있지만 반드시 알아야 하진 않음

듣기를 멈추고 반응을 시작하자!


🧱 복잡도의 벽

  • 큰 프로젝트는 복잡도로 인해 진행 지연, 초기화, 인력 증가, 리팩터링 필요
  • FRP는 이벤트 전달이라는 복잡도 근원을 해결하려는 방식

🔍 함수형 반응형 프로그래밍이란?

  • 관찰자 패턴 대체
  • 이벤트 중심 로직을 조합 가능한 방식으로 표현
  • 프로그램을 "입력 → 출력" 흐름으로 정의
  • 상태를 구조화

🎯 정의

  1. 표시적
    • 타입/구성요소의 의미를 정확히 명세
  2. 시간 연속적

🧪 소듐(Sodium) 소개

  • 다양한 언어 지원
  • 진정한 FRP 철학 구현
  • 최소주의 설계, 학습에 적합

📍 FRP의 위치

  • 함수형 프로그래밍(FP): 불변성, 합성성
  • 반응형 프로그래밍(RP): 이벤트 흐름
  • FRP = FP + RP의 교집합

🎈 이벤트와 대화형 앱

  • 스레드 기반 vs 이벤트 기반
  • 상태 기계 모델은 순서 의존, 유지 어려움
  • 리스너 기반 접근은 문제 발생 빈도 높음

⚠️ 리스너의 여섯 가지 문제

  1. 예측 불가한 순서
  2. 첫 이벤트 소실
  3. 지저분한 상태
  4. 스레드 문제
  5. 콜백 누수
  6. 의도치 않은 재귀

🚫 리스너를 개선하지 않는 이유

  • 리스너 구조를 유지하면 반복되는 문제
  • FRP는 기존의 방식 자체를 재설계

🔁 상태와 셀

  • 일반 변수는 순서 민감
  • FRP는 셀(Cell)로 상태를 캡슐화
  • 변경 통지/실행 순서를 자동 처리
Cell<Boolean> valid = dep.date.lift(ret.date, (d, r) -> d.compareTo(r) <= 0);

🧠 패러다임 전환

  • OOP적 순서 → FRP의 의존 관계 중심
  • 실행 순서를 직접 기술하지 않음
  • 선언적 사고 필요

🧩 선언적 사고란?

  • 어떻게보다 무엇을 정의
  • 조작적 정의 vs 개념적 정의
  • 조합 가능성과 재사용성 강조

⚙️ FRP 실행 흐름

  1. 초기화: 의존 관계 그래프 구성
  2. 실행: 입력 → 내부 계산 → 출력

🌊 스트림과 셀

  • Cell: 시간에 따라 변하는 값
  • Stream: 이벤트의 흐름

🎛 Rule 클래스 예제

Rule r1 = new Rule((d, r) -> d.compareTo(r) <= 0);
Rule r2 = new Rule((d, r) -> !unlucky(d) && !unlucky(r));
Rule r = r1.and(r2);
  • 규칙을 조합할 수 있음 (합성성)

✅ 요약

  • FRP는 리스너/콜백의 한계를 해결하는 선언적 패러다임
  • 방향성 그래프 기반 구조
  • 프로그램을 관계 중심으로 표현
  • 복잡도는 낮추고 유지보수성은 높인다