ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수형 프로그래밍(FP) - 액션과 계산, 데이터
    CS지식/함수형 프로그래밍 2024. 3. 26. 15:42

    액션과 계산, 데이터

    액션

    실행 시점과 횟수에 의존한다. 다른말로 부수효과(side-effects), 부수효과가 있는 함수(side-effecting function), 순수하지 않은 함수(impure function)라고 부르기도 한다.

    ex) 이메일 보내기, 데이터베이스 읽기

     

    계산

    입력값을 계산해 출력같은 반환한다. 다른함로 순수함수(pure function)부르기도 한다.

    ex) 최댓값 찾기, 이메일 주소가 올바른지 확인하기

     

    데이터

    이벤트에 대한 사실

    ex) 사용자가 입려간 이메일 주소, 은행 API로 읽은 달러 수량


    액션과 계산, 데이터는 어디나 적용할 수 있다.

    일상에서 자주하는 활동인 장보기에 액션과, 계산 데이터를 적용해보자

     

    함수형 프로그래밍이 아닌 방법으로 장보기 과정을 그린다면 아래 그림 처럼 그릴수 있다. 또 각 단계가 액션과 계산, 데이터중 어떤 종류에 속하는지도 표시해 보자 

    모든 것이 액션이라니... 뭔가 놓친것이 있을 수도 있다. 물론 아주 단순한 과정은 액션으로만 분류할 수 있지만 위에서 살펴본 장보기 과정은 그렇게 단순하지는 않다. 놓친것이 없는지 단계별로 살펴보자.

     

    냉장고 확인하기

    냉장고를 확인하는 일은 확인하는 시점이 중요하기 때문이다. 액션이다. 냉장고에 가지고 있는 제품은 데이터이다. 이것을 현재 재고(current inventory)라고 한다.

     

    운전해서 상점으로 가기

    운전해서 상점으로 가는 것은 복잡한 행동이고 명확히 액션이다. 하지만 여기엔 사실 데이터가 숨어있다. 상점의 위치나 가는 경로는 데이터로 볼 수 있다. 하지만 자율 주행 자동차를 만드는 것은 아니기 때문에 따로 분리하지는 않는다.

     

    필요한 것 구입하기

    구입하는 일도 확실히 액션이다. 하지만 구입 과정은 몇 단계로 나눌 수 있다. 필요한 것을 구입하려면 필요한 것이 무엇인지 알아야 한다. 필요한 것은 어떻게 알 수 있을까? 어떻게 장을 볼지에 따라 다르겠지만 필요하지만 없는 제품의 목록을 만드는 것이 가장 쉽다.

    앞에 '냉장고 확인하기' 단계에서 만든 현재 재고 데이터를 사용했다. 이제 '필요한 것 구입하기' 단계를 몇 단계로 더 나눌 수 있다.

     

    • 재고 '빼기'는 같은 입력값일 때 항상 같은 결과값을 주기 때문에 계산이다.
    • 어떤 것을 결정하는 일은 계산으로 표현할수 있다.
    • 장보기 목록을 결정하는 것은 계산이다. 실제 구입하는 단계와 구입할 것을 결정하는 단계는 나눌수 있다.
    • 구분하는 것이 결국 액션과 계산을 나누는 것이다.

     

     

    액션과 계산, 데이터를 더 명확하게 하기 위해 액션과 계산, 데이터에 해당하는 단꼐를 각각 다른 열에 그려 보자 데이터는 액션과 계산의 입력과 출력으로 사용되기 때문에 선으로 연결한다.

     

     

    이렇게 반복하면 액션과 계산, 데이터를 더 많이 찾을 수 있고 풍부한 모델을 만들 수 있다. 예를들어 '냉장고 확인하기' 단계는 '냉장실 확인하기' 단계와 '냉동실 확인하기' 단계로 나눠 액션으로 만들 수 있다. 각각 액션은 데이터를 만들 수 있고 연결할 수 있다. '목록에 있는 것 구입 하기' 단계도 '장바구니에 담기'와 '계산하기' 단계로 나눌 수 있다.

     

    계속 나누다 보면 점점 더 복잡해진다고 생각할 수 있다. 하지만 액션에 숨어 있는 다른 액셔니아 계산 또는 데이터를 발견하기 위해 나눌 수 있는 만큼 나누는 것이 좋다. 


    장보기 과정에서 배운 것

    • 액션과 계산, 데이터는 어디에나 적용할 수 있다.
      • 처음에는 액션과 계산, 데이터를 적용하기 어려울 수 있지만 연습을 할 수록 더 잘할 수 있다.
    • 액션 안에는 계산과 데이터, 또 다른 액션이 숨어 있을 수 있다.
      • 단순해 보이는 액션 또 다른 액션이나 계산, 데이터로 나눌수 있다. 함수형 프로그래밍에서는 액션을 더 작은 액션과 계산, 데이터로 나누고 나누는 것을 언제 멈춰야 할지 아는 것이 중요하다.
    • 계산은 더 작은 계산과 데이터로 나누고 연결할 수 있다. 
      • '필요 한것 구입하기' 단계에서 계산에 필요한 데이터를 찾았다. 
      • 어떤 경우 계산을 더 작은 계산으로 나누는 것이 더 좋을 때도 있다. 계산을 나누면 첫 번째 계산의 결과 데이터가 두 번째 계산의 입력이 된다.
    • 데이터는 데이터만 조합할 수 있다.
      • 데이터는 다른 영향을 주지 않는 그냥 데이터이다. 그래서 데이터를 찾는 일을 먼저 해야한다.
      • 데이터를 찾았다면 동작에 대해 많은 것을 알 수 있다.

     

    💡tip) 데이터

    불변성
    함수형 프로그래밍은 불변 데이터 구조를 만들기 위해 두가지 원칙을 사용한다.
    1. 카피 오 라이트(copy-on-write) : 변경할 대 복사본을 만든다.
    2. 방어적 복사(defensive copy) : 보관하려고 하는 데이터의 복사본을 만든다.

    데이터의 장점
    역설적으로 데이터는 데이터 자제로 할 수 있는 것이 없기 때문에 좋다. 그래서 데이터는 데이터 그대로 이해할 수 있다.
    1. 직렬화 : 직렬화된 액션과 계산은 다른 곳에서 잘 동작할 것이라는 보장이 없다. 하지만 직렬화된 데이터는 전송하거나 디스크에 저장했다가 읽기 쉽다.
    2. 동일성 비교 : 계산이나 액션은 서로 비교하기 어렵다. 하지만 데이터는 비교하기 쉽다.
    3. 자유로운 해석 : 데이터는 여러 가지 방법을로 해석할 수 있다. 접속 로그는 문제 해결을 위해 사용할 수도 있지만 , 모니터링을 위해 사용할 수도 있다.

    새로 만드는 코드에 함수형 사고 적용하기 

    쿠폰독의 새로운 마케팅 전략

    쿠폰독은 쿠폰에 관심 있는 구독자들에게 이메일로 쿠폰을 매주 보내주는 서비스이다. 사용자도 많고 인기 있는 서비스이다. 

     

    쿠폰독 CMO(chief marketing offier)는 사용자를 더 늘리기 위해 친구 10명을 추천하면 더 좋은 쿠폰을 보내주려고한다. 쿠폰독은 커다란 이메일 데이터베이스가 있다. 여기에는 이메일별로 각 사용자가 추천한 친구 수도 기록하고 있다.

     

    쿠폰에 대한 정보를 가지고 있는 데이터베이스도 있다.  쿠폰 데이터베이스는 각 쿠폰에 'low','middle','high'와 같은 등급rank 정보도 있다. 'high'과 같은 등급rank 정보도 있다. 'high'쿠폰은 추천을 많이 한 사용자를 위한 쿠폰이다.'middle' 쿠폰은 모든 사용자들에게 전달되는 쿠폰이고 'bad' 쿠폰은 사용하지 않기 때문에 사용자에게 전달하지 않는다.

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

     

     

    1.데이터베이스에서 구독자를 가져오는 것부터 시작한다.

    쿠폰을 이메일로 보내려면 언저 데이터베이스에서 구독자를 가져와야 한다. 이 단계는 액션이다. 구독자는 계속 바뀌기 때문에 지금 가져온 구독자와 다음에 가져온 구독자는 다를 수 있다. 그래서 이 단계는 실행 시점에 의존한다. 구독자를 데이터베이스에서 가져오면 사용자 목록을 얻을 수 있고, 이것은 데이터 이다. 

     

     

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

     

    데이터베이스에서 쿠폰 목록을 가져오는 것도 액션이다. 쿠폰 데이터베이스는 계속 바뀌기 때문에 가져오는 시점이 중요하다. 그래서 한번 가져오 쿠폰 목록은 가져온 시저의 목록이다. 그리고 가져온 쿠폰 목록은 데이터이다. 쿠폰 목록 데이터는 DB쿼리 이벤트에 대한 사실이라고 할수 있다. 

     

    데이터베이스에서 구독자 목록과 쿠폰 목록 데이터를 얻었기 때문에이 데이터를 사용해 어떤 결정을 할 수 있다. 다음 단계에서 해당 데이터로 어떤 사용자가 어떤 쿠폰을 받을지 결정할 수 있다.

     

    3. 보내야 할 이메일 목록 만들기

    처리 과정에서 필요한 데이터를 만들기도 한다. 장을 볼 때 돌아다니면서 생각나는 것을 사지 않고 장보기 전에 목록을 만드는 것과 비슷하다.

    '이메일 목록 계획하기'에서 생성된 이메일 목록은 다음 단계에서 사용할 데이터이다. 이메일 목록은 보내야 할 이메일을 계획한 결과이다.

     

    4.이메일 전송하기 

    이제 계획한 이메일을 보낼 수 있다. 이메일을 전송하는 작업은 간단하다. 이메일을 전송하는 작업은 간단한다. 이메일 목록 데이터에는 수신자와 보낼 내용이 모두 세팅되었기 때문에 목록을 순회하면서 그냥 보내면 된다. 여기서 중요한 것은 미리 계획 단계를 거쳤다는 것이다. 


    이메일 만드는 부분을 자세히 살펴보기

    이메일 목록을 계획하는 계산을 더 작은 계산으로 나눠보자.

    이메일 목록을 계획하는 계산은 구독자 목록 데이터와 쿠폰 목록 데이터를 받는다. 그리고 계산한 결과는 이메일 목록이다.  함수형 프로그램밍은 일반적으로 가능하면 액션을 사용하지 않을려고 합니다. 그리고 계산으로 바꿀 수 있는 액션이 있다면 그렇게 하는 것이 좋다.

     

    가능한 계산을 사용하려고 하는 이유는 테스트하기 쉽게 때문이다. 이메일을 실제로 보내고 결과를 주는 시스템은 테스트 하기 어렵다. 하기만 결과가 이메일 목록 데이터인 시스템은 테스트 하기 쉬다. 

     

     

    1.이메일 목록을 계획하는 계산 더 작은 계산으로 나누기 

     

    2.good 쿠폰 목록 best 쿠폰 목록을 계산

     

    3.어떤 구독자가 어떤 쿠폰을 받을지 계산 

    4.최종적으로 구독자가 어떤 내용의 이메일을 받을지 계산 

    이미 있는 코드에 함수형 사고 적용하기 

     

    다음은 자회사에 수수료를 보내기 위해 만든 코드이다. sendPayout() 함수는 실제 은행 계좌로 송금하는 액션이다. 

    funtion figurePayout(affiliate){
        const owed = affiliate.sales * affiliate.commission;
        if(owed > 100) // 100달러 이하면 송금하지 않기
        sendPayout(affiliate.bank_code, owed);
    }
    
    function affiliatePayment(affiliates){
        for(const a of affiliates)
        figurePayout(a);
    }
    
    function main(affiliates){
       affiliatePayout(affiliates);
    }

     

    액션의 정의에 따르면 애션은 호출 시점이나 횟수에 의존한다. figurePayout() 함수는 액션인 sendPayout()함수를 호출하기 때문에 역시 호출 시점과 횟수에 의존하게된다. 그래서 figurePayout()함수 역시 액션이 된다. 

     

    더군다나 액션을 호출하는 main()함수도 같은 논리로 액션이 되는 것을 피할 수 없다. 결국 드 안쪽에 액션을 호출하는 작은 코드 하나가 전체 프로그램을 액션으로 만든다. 

     

    위에서 본 것 처럼 액션은 사용하기 참 어렵다. 액션을 부르는 함수가 있다면 그 함수도 액션이 된다.  액션을 부르는 함수가 있다면 해당 함수도 액션이 된다. 또 그 함수를 부르는 다른 함수도 역시 액션이 된다. 이런 식으로 작은 액션하나가 코드 전체로 퍼져 나간다.

     


    액션은 다양한 형태로 나타난다. 

    함수형 프로그래밍을 배우려면 액션을 관리하는 법을 배워야 합니다. 액션을 관리하기 위해서 액션이 토드에서 어떤 형태로 나타나는지도 알아야한다. 자바스크립트에서 발생할 수 있는 액션을 살펴보자

     

    함수호출

    alert("Hello world");

     

    팝업 차이 뜨는 액션이 발생한다.

     

    메서드 호출

    console.log("hello");

     

    콘솔에 출력한다.

     

    생성자 

    new Date()

     

    기본적으로 부는 시점에 현재 날짜와 시간을 초기화하기 때문에 호출되는 시점에 따라 다른 값을 가진다.

     

    표현식

    //참조 변수
    y
    
    //속성 참조
    user.first_name
    
    //배열 참조
    satck[0]

     

    y, user, stack과 같은 변수,인스턴스,배열이 공유되고 변경 가능한 배열이라면 읽는 시점에 따라 값이 다를 수 있다.

     

    상태

    //값 할당
    let = 3;
    
    //속성 삭제
    delete user.first_name;

     

    공유하기 위해 값을 할당했고 변경 가능한 변수라면 다른 코드에 영향을 주기 때문에 액션이다. 속성을 지우는 것이 다른 코드에 영향을 줄 수 있기 때문에 액션이다. 

     

    위에 든 예시들은 모두 액션이다. 언제 부르는지 또 얼마나 부르즌지에 따라 다른 결과를 낼 수 있다. 어느 곳에서나 사용할 수 있기 때문에 코드 전체로 퍼지기 쉽다.  또 액션을 찾기위해서 코드가 호출 시점이나 횟수에 의존하는지 생각해보면 된다. 


    액션에 대해 자세히 알아보기

    액션이 무엇일까?

    • 순서 - 언제 실행되는지 
    • 반복 - 얼마나 실행되는지  

    액션은 외부 세계의 영향을 주거나 받는 것을 말한다. 그리고 액션은 실행 시점가 횟수에 의존한다.

     

    액션은 어떻게 구현할까?

    자바스크립트에서는 함수로 구현한다. 계산도 함수로 구현하기 때문에 구분하기 쉽지 않을 수 있다. 계산과 액션을 구분하는 방법에 대해 더 생각해보자.

     

    어떻게 액션에 의미를 담을 수 있을까?

    ex)

    • 이메일 보내기
    • 계좌에서 인출하기
    • 전역변수값 바꾸기
    • axios로 요청 보내기

    액션으로 외부 세상에 영향을 줄 수 있다. 따라서 어떤 일을 하려고 하는지 잘 파악하는 것이 중요하다.


    정리

    액션과 계산, 데이터를 여러가지 상황에 적용해 봤다. 계산은 계획이나 결정을 할 때 적용했고, 데이터는 계획하거나 결정한 결과였다. 마지막으로 액션을 통해 계산으로 만든 계획을 실행할 수 있다.

     

     

    [출처- 쏙쏙 들어오는 함수형 코딩, 저 에릭 노먼드]

    https://jpub.tistory.com/1265

     

    쏙쏙 들어오는 함수형 코딩

    심플한 코드로 복잡한 소프트웨어 길들이기 도서구매 사이트(가나다순) [교보문고] [도서11번가] [알라딘] [예스이십사] [인터파크] [쿠팡]전자책 구매 사이트(가나다순)[교보문고] [구글북스] [리

    jpub.tistory.com

     

    댓글

Designed by Tistory.