mingg IT

[함수형 프로그래밍] 3장 액션과 계산, 데이터의 차이를 알기 본문

FrontEnd

[함수형 프로그래밍] 3장 액션과 계산, 데이터의 차이를 알기

mingg123 2023. 9. 23. 15:30

액션

 

  • 실행 시점과 횟수에 의존
  • 부수 효과, 부수 효과가 있는 함수, 순수하지 않은 함수
  • ex) 이메일 보내기, 데이터베이스 읽기 

 

계산

 

  • 입력으로 출력을 계산
  • 순수함수, 수학 함수
  • ex) 최댓값 찾기, 이메일 주소가 올바른지 확인하기 

 

데이터

 

  • 이벤트에 대한 사실
  • ex) 사용자가 입력한 값, API로 읽은 값 

 

 

액션, 계산, 데이터를 구분 하는 시점

 

  • 문제에 대해 생각할 때
  • 코딩할 때 
    • 최대한 액션에서 계산을 빼냄
    • 계산에서는 데이터를 분리할 수 있는지 검토
    • 액션이 계산이 될 수 있는지, 계산은 데이터가 될 수 있는지 고민 
  • 코드를 읽을 때
    • 액션, 계산, 데이터 중 어떤 것에 속하는지 살펴보기
    • 액션은 시간에 의존하기 때문에 더욱 조심히

 

액션, 계산, 데이터 구분 예시

 

 

전부다 액션임. 각 플로우를 좀 더 세분화 해보자

 

 

냉장고 확인하기

 

  • 냉장고를 확인하는 일은 시점이 중요하기 때문에 액션
  • 냉장고 안에 있는 제품은 데이터 

 

운전해서 상점으로 가기

 

  • 운전해서 상점으로 가는 것은 액션
  • 상점위치나 가는 경로는 데이터

 

필요한 것 구입하기

 

  • 구입하는 것도 액션
  • 구입하는 항목은 [냉장고 확인하기] 에서  만든 재고 데이터를 이용 

구입 항목은 데이터와 계산으로 이루어져 있음. 

 

운전해서 집으로 오기 

 

액션과 데이터를 더 나눌 순 있지만 굳이 나누진 않겠다. (액션으로 두겠음)

 

 

플로우를 정리하면 다음과 같음. 

 

요약

 

  • 액션 안에는 계산과 데이터, 또 다른 액션이 숨어져 있을 수 잇음
  • 계산은 더 작은 계산과 데이터로 나누고 연결할 수 있음 
  • 데이터는 데이터만 조합할 수 있음
  • 계산은 때로 우리 머릿속에서 일어남 (계산 단계가 잘 보이지 않는 이유)

 

 


 

 

데이터

 

  • 이벤트에 대한 사실
  • 일어난 일의 결과를 기록한 것
  • 구현 방법
    • JS에서 숫자나 문자, 배열, 객체
  • 불변성
    • copy-on-wirte: 변경할 때 복사본을 만듬
    • defensive copy: 보관하려고 하는 데이터의 복사본을 만듬 
  • 장점
    • 직렬화
      • 직렬화된 데이터는 전송하거나 저장했다가 읽기 쉽다 (함수보다 더 오래 사용한다)
    • 동일선 비교
      • 비교하기 쉽다(액션이나 계산에 비해)
    • 자유로운 해석
      • 접속 로그는 문제 해결을 위해 사용할 수 있음 
  • 단점
    • 해석이 반드시 필요하다 (계산은 해석하지 않아도 실행할 수 있다)

 


 

쿠폰을 이메일로 보내주는 서비스 예시

 

  • 10명 이상 추천한 사용자는 더 좋은 쿠폰을 받을 수 있다. 

만들어야할 서비스 

  • 이메일 보내기
  • 데이터베이스 구독자 가져오기
  • 데이터베이스에 이메일 가져오기 
  • 쿠폰에 등급 매기기 
  • 추천 수에 따라 어떤 쿠폰을 보내줄지 계산하기

 

 

쿠폰 보내는 과정

 

1. 데이터베이스에서 구독자 정보를 가져온다  (액션)

 

2. 데이터베이스에서 쿠폰 목록 가져오기  (액션)

 

3. 보내야 할 이메일 목록 만들기  (이메일 목록: 데이터)

 

이메일 목록을 만드는 디테일한 부분 (계산)

계산을 사용하는 이유

  • 테스트를 쉽게 하기 위해

 

3-1) 쿠폰과 회원 데이터를 들고옴

3-2) 어떤회원이 어떤 쿠폰을 받는지 계산하는 함수를 만듬

3-3) 특정 등급의 쿠폰 목록을 선택하는 계산을 하는 함수를 만듬  (입력: 쿠폰리스트, 등급/ 출력: 쿠폰 리스트)

-> (couponList, 'good') 하면 good 인 쿠폰 리스트만 출력 

 

       

 

4.  이메일 전송하기  (액션)

 

4-1) 이메일은 그냥 데이터임

4-2) 구독자가 받을 이메일을 계획하는 계산 

subCouponRank함수로 구독자가 어떤 쿠폰을받을지 best or good을 리턴함 

 

4-3) 보낼 이메일 목록 준비하기

 

함수이름이 emailForSubscribers라서 헷갈렸음. 모든 구독자들에게 보낼 이메일 리스트를 만드는 함수임 

 

4-4) 이메일 보내기 

sendIssue함수로 모든 기능을 하나로 묶음.

함수이름이랑 var e로 하는거 넘 헷갈림 코드 읽을 때 

 

구현 순서

 

  • 데이터를 파악
  • 계산과 추가 데이터를 도출
  • 액션으로 모든 것을 묶음

데이터는 사용하는데 제약이 많고 액션은 가장 제약이 없음 

 

 

Q&A

 

  • 일정을 보내기 전에 왜 모든 이메일을 만드나요? 비효율적이지 않나요? 사용자가 수백명이면 어떻게 하냐?
    • 사용자가 많다면 메모리 부족으로 시스템이 동작하지 않을 수도 있음. 
    • 확장성을 고려해서 만든다면 구독자 배열을 만드는 함수 emailsForSubscribers() 함수를 청크단위로 잘라서 읽으면 됨 

  • 계산은 고쳐지지 않았다는것이 중요함 
  • 데이터베이스에서 메모리로 읽어오는 것은 액션임. 

 


계산

 

  • 입력값으로 출력값을 만드는 것 
  • 실행 시점과 횟수에 관계없이 항상 같은 입력값에 대해 같은 출력값을 돌려줌 
  • 함수로 구현
  • 액션보다 좋은 이유?
    • 테스트 하기 쉬움
    • 기계적인 분석이 쉬움
    • 조합해서 더 큰 계산을 만들 수 있음 
  • ex) +, *, concat, 쇼핑계획하기(?)
  • 계산을 사용하면 걱정하지 않아도 되는 것
    • 동시에 실행되는 것
    • 과거에 실행되었던 것이나 미래에 실행할 것
    • 실행 횟수 
  • 단점
    • 실행 전에 어떤 일이 발생할지 알 수 없음
    • 입력값으로 실행해야 결과를 알 수 있음 

 


 

이미 있는 코드에 함수형 사고 적용 예시

 

  • sendPayout만 액션으로 보이지만, 액션을 호출하는 함수도 액션임
  • 결국 세 함수 모두 액션임 

전역적으로 퍼진 이 액션을 어캐 바꿀래? => 뒤에서 알려준다함 궁금한데.. 

 

 

다양한 액션 예시

 

 

액션

 

  • 실행 시점과 횟수에 의존
  • JS에서 함수로 구현
  • ex) 이메일 보내기, 계좌에서 인출하기, 전역변숫값 바꾸기, ajax 요청하기
  • 순수하지 않은 함수, 부수 효과 함수, 부수 효과가 있는 함수 
  • 액션은 함수형 프로그래밍에서 가장 중요함 
  • 액션은 다루기 힘듬. 소프트웨어를 실행하려는 가장 중요한 이유임
  • 가능한 액션을 적게 사용하자 (전혀 사용하지 않을 순 없다)
  • 액션 관련된 기능은 작게 만들자. 액션과 관련 없는 코드는 모두 제거하자
  • 액션이 외부 세계와 상호작용하는 것을 제한할 수 있음. 내부에 계산과 데이터만 있고 가장 바깥쪽에 액션이 있는 구조가 이상적임
  • 액션이 호출 시점에 의존하는 것을 제한함 

 

요약

 

  • 액션은 실생 시점이나 횟수에 의존함. 외부 세계에 영향을 주거나 받음
  • 계산은 입력 값으로 출력값을 만듬. 외부 세계에 영향을 주거나 받지 않고 실행 시점이나 횟수에 의존하지 않음
  • 데이터는 이벤트에 대한 사실임. 사실은 변하지 않기 때문에 영구적으로 기록 할 수 있음
  • 함수형 프로그래머는 액션보다 계산을 좋아하고 계산 보다 데이터를 좋아함
  • 계산은 같은 입력값을 주면 항상 같은 출력값이 나오기때문에 액션보다 테스트하기 쉬움

 

Comments