\(@^0^@)/

[BOOK] 쏙쏙 들어오는 함수형 코딩 3 본문

BOOKS/Grokking simplicity 함수형 코딩

[BOOK] 쏙쏙 들어오는 함수형 코딩 3

minjuuu 2022. 7. 27. 23:08
728x90

액션과 계산, 데이터의 차이를 알기

챕터 1부터 계속 말하고 있지만, 다시 한번 정리해보자.

액션

  • 실행 시점과 횟수에 의존한다.
  • 다른 말로 부수 효과(side-effects), 부수 효과가 있는 함수(side-effecting function),
    순수하지 않은 함수(impure function)라고 부르기도 한다.
  • ex) 이메일 보내기, 데이터 베이스 읽기

계산

  • 입력으로 출력을 계산한다.
  • 다른 말로 순수 함수(pure function), 수학 함수(mathematical function)라고 부르기도 한다.
  • 계산은 계산을 호출하는 코드를 계산 결과로 바꿀 수 있기 때문에 참조 투명(referentially transparent)한다.
  • ex) 최댓값 찾기, 이메일 주소가 올바른지 확인하기

데이터

  • 이벤트에 대한 사실
  • ex) 사용자가 입력한 이메일 주소, 은행 API로 읽은 달러 수량

모든 개발 과정에서 액션과 계산, 데이터를 구분하는 기술을 아래와 같이 적용해 볼 수 있다.

1. 문제에 대해 생각할 때
아직 코딩을 시작하기 전 문제에 대해서 고민하고 있을 때, 문제를 액션과 계산, 데이터로 나눠 생각해 볼 수 있다.
그렇게 나눠서 코드를 작성한다면 특별히 주의해야 할 부분(액션)과 데이터로 처리해야 할 부분, 결정을 내려야 하는 부분(계산)을 명확히 알 수 있다.

2. 코딩할 
함수형 프로그래머는 최대한 액션에서 계산을 빼내려고 한다.
또 계산에서는 데이터를 분리할 수 있는지 생각한다. 더 나아가 액션이 계산이 될 수 있는지, 계산은 데이터가 될 수 있는지 생각한다.

3. 코드를 읽을 때

코드를 읽을 때 액션과 계산, 데이터 중 어떤 것에 속하는지 잘 살펴봐야 한다.
특히 액션은 시간에 의존하기 때문에 더 조심해야 한다. 그래서 숨어있는 액션까지도 찾아야 한다.


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

우리가 일상에서 자주 하는 장보기에 액션과 계산, 데이터를 적용해보자.

함수형 프로그래머가 아닌 프로그래머가 장보기 과정을 그릴 경우에
장보기 과정 : 냉장고 확인하기 -> 운전해서 상점으로 가기 -> 필요한 것 구입하기 -> 운전해서 집으로 오기

  • 냉장고 확인하기
    • 이 단계는 액션이 확실하다. 냉장고를 확인하는 시점에 따라 냉장고에 있는 제품이 다르기 때문.
      내일 확인한다면 우유가 없을지도 모른다.
  • 운전해서 상점으로 가기
    • 이 단계 역시 액션이다. 두 번 운전해서 상점에 가면 연료가 두 배로 든다.
  • 필요한 것 구입하기
    • 구입하는 것 또한 액션이다. 누군가 브로콜리를 구입하면 브로콜리가 다 떨어질 수도 있기 때문에 구입하는 시점이 중요하다.
  • 운전해서 집으로 오기
    • 역시 액션이다. 이미 집에 있다면 상점에 있는 것이 아니기 때문에 상점에서 집으로 올 수 없음.
      언제 하는지가 중요한 단계

모든 단계가 액션이라면, 계산과 데이터는 어디에 있는 걸까? 놓친 것이 있는지 단계별로 다시 살펴보자.

  • 냉장고 확인하기
    • 냉장고를 확인하는 일은 확인하는 시점이 중요하기 때문에 액션이다.
      냉장고에 가지고 있는 제품은 데이터다. 이것을 현재 재고(current inventory)라고 한다.
  • 운전해서 상점으로 가기
    • 운전해서 상점으로 가는 것은 복잡한 행도이고 명확히 액션이다.
      하지만 여기에는 데이터가 숨어 있다. 상점 위치나 가는 경로는 데이터로 볼 수 있음.
  • 필요한 것 구입하기
    • 구입하는 일도 확실히 액션. 하지만 구입 과정은 몇 단계로 나눌 수 있다.
      필요한 것을 구입하려면 필요한 것이 무엇인지 알아야 한다. 필요하지만 장을 볼 필요는 없는 제품의 목록을 만드는 것이 가장 쉽다.
      현재 재고 파악 -> 필요한 재고 파악 -> 재고 빼기 -> 장보기 목록 -> 목록에 있는 것 구입하기
  • 운전해서 집으로 오기

앞에 이야기한 내용을 반영해서 다시 정리해보자.

  • '냉장고 확인'의 결과는 '현재 재고'이다.
  • '재고 빼기'는 입력 데이터가 두 개 필요하다.
  • '재고 빼기'의 결과는 '장보기 목록'이다.
  • '목록에 있는 것 구입'은 '장보기 목록'을 입력값으로 사용한다.

이렇게 반복하면 액션과 계산, 데이터를 더 많이 찾을 수 있고 풍부한 모델을 만들 수 있다.
계속 나누다 보면 점점 더 복잡해진다고 생각할 수 있지만, 액션에 숨어 있는 다른 액션이나 계산 또는 데이터를 발견하기 위해 나눌 수 있는 만큼 나누는 것이 좋다.


장보기 과정에서 배운 것

1. 액션과 계산, 데이터는 어디에나 적용할 수 있다.
2. 액션 안에는 계산과 데이터, 또 다른 액션이 숨어 있을지도 모른다.
3. 계산은 더 작은 계산과 데이터로 나누고 연결할 수 있다.
4. 데이터는 데이터만 조합할 수 있다.
5. 계산은 때로 '우리 머릿속에서' 일어난다.


데이터에 대해 자세히 알아보기

  • 데이터는 무엇인가?
    • 데이터는 이벤트에 대한 사실이다. 일어난 일의 결과를 기록한 것.
  • 데이터를 어떻게 구현하나?
    • JS에서는 기본 데이터 타입으로 구현한다.
      숫자나 문자, 배열, 객체 같은 것.
    • 다른 언어에서는 더 정교한 방법으로 데이터를 만들 수 있다.
      ex) 하스켈은 새로운 데이터 타입을 정의해 도메인을 표현한다.
  • 어떻게 데이터에 의미를 담을 수 있나?
    • 데이터 구조로 의미를 담을 수 있다.
      ex) 목록의 순서가 중요하다면 순서를 보장하는 데이터 구조를 사용하면 된다.
      데이터 구조로 도메인을 표현할 수 있다.
  • 불변성
    • 함수형 프로그래머는 불변 데이터 구조를 만들기 위해 두 가지 원칙을 사용한다.
      • 카피-온-라이트(copy-on-write) : 변경할 때 복사본을 만든다.
      • 방어적 복사(defensive copy) : 보관하려고 하는 데이터의 복사본을 만든다.
  • 데이터의 예
    • 구입하려는 음식의 목록
    • 이름
    • 전화번호
    • 음식 조리법
  • 데이터의 장점
    • 역설적으로 데이터는 데이터 자체로 할 수 있는 것이 없기 때문에 좋다.
      그래서 데이터는 데이터 그대로 이해할 수 있다.
    • 직렬화 : 직렬화된 액션과 계산은 다른 곳에서 잘 동작할 것이라는 보장이 없다.
      하지만 직렬화된 데이터는 전송하거나 디스크에 저장했다가 읽기 쉽다.
    • 동일성 비교 : 계산이나 액션은 서로 비교하기 어렵지만 데이터는 쉽다.
    • 자유로운 해석 : 데이터는 여러 가지 방법으로 해석할 수 있다.
  • 데이터의 단점
    • 유연하게 해석할 수 있다는 점은 장점이지만, 해석이 반드시 필요하다는 점은 단점.
  • 사전적 정의
    • 이벤트에 대한 사실 : 데이터는 해석이 필요하다는 것을 내포하고 있다.
      대부분의 데이터는 여러 단계의 해석 과정을 거친다.
      ex) 사용자 정보 데이터는 바이트로부터 시작해 문자나 JSON 같은 해석 과정을 거칠 수 있다.
      웹 요청을 해석하는 여러 단계 : 바이트 -> 문자 -> JSON -> 컬렉션 -> 사용자 정보
    • 사실 정보는 추론과 토론, 계산을 위한 기초 정보로 사용 : 소프트웨어 엔지니어가 정보를 처리하는 시스템을 만든다는 것을 강조한다. 정보를 처리하는 시스템은 정보를 받고 처리한 후에(오류가 생길 수 있음) 결정을 하고(무엇을 저장하고 누구에게 이메일을 보낼지), 결정에 따라 특정 행동(이메일 보내기)을 한다.

계산에 대해 자세히 알아보기

  • 계산은 무엇인가?
    • 계산은 입력값으로 출력 값을 만드는 것.
    • 실행 시점과 횟수에 관계없이 항상 같은 입력값에 대해 같은 출력 값을 돌려준다.
  • 계산은 어떻게 구현하나?
    • 계산은 함수로 구현한다.
  • 어떻게 계산에 의미를 담을 수 있나?
    • 계산에는 연산을 담을 수 있다. 계산은 입력값을 출력 값으로 만드는 것을 표현한다.
    • 계산을 언제 사용할지 또는 어떻게 사용할지는 때에 따라 다르다.
  • 왜 액션보다 계산이 좋은가?
    1. 테스트하기 쉽다. 계산은 언제 어디서나 (로컬 장비, 빌드 서버, 테스트 장비) 원하는 만큼 테스트를 실행할 수 있다.
    2. 기계적인 분석이 쉽다.
    3. 계산은 조합하기 좋다. 계산을 조합해 더 큰 계산을 만들 수 있다.
  • 계산의 예
    • 더하기나 곱하기
    • 문자열 합치기
    • 쇼핑 계획 하기
  • 계산을 쓰면서 걱정하지 않아도 되는 것
    1. 동시에 실행되는 것
    2. 과거에 실행되었던 것이나 미래에 실행할 것
    3. 실행 횟수
  • 계산의 단점
    • 계산과 액션은 실행하기 전에 어떤 일이 발생할지 알 수 없다는 단점이 있다.
    • 물론 코드를 읽으면 예상할 수 있지만, 소프트웨어 측면에서 함수는 블랙박스이다.
      입력값으로 실행해야 결과를 알 수 있다. 이러한 단점이 싫다면 계산이나 액션 대신 데이터를 사용해야 한다.
  • 계산은 일반적으로 무엇이라고 하나?
    • 다른 책에서 보통 순수 함수(pure function)또는 수학 함수(mathematical function)라고 부른다.
    • 이 책에서는 계산이라고 부르고 있다.

 액션은 코드 전체로 퍼진다.

액션을 부르는 함수가 있다면 그 함수도 액션이 된다. 또 그 함수를 부르는 다른 함수도 역시 액션이 된다.
이런 식으로 작은 액션 하나가 코드 전체로 퍼져 나간다. 그렇기 때문에 함수형 프로그래머는 액션을 쓰는 순간 코드 전체로 퍼져나가기 때문에 가능한 사용하지 않으려고 한다.

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

자바스크립트에서 발생할 수 있는 액션을 살펴보자.

  • 함수 호출
    • alert("hello world")
      팝업 창이 뜨는 것은 액션.
  • 메서드 호출
    • console.log("hello")
      콘솔에 출력
  • 생성자
    • new Date()
      기본적으로 부르는 시점에 현재 날짜와 시간을 초기화하기 때문에 호출되는 시점에 따라 다른 값을 가진다.
  • 표현식
    • 변수 참조 - y
      • y가 공유되고 변경 가능한 변수라면 읽는 시점에 따라 값이 다를 수 있다.
    • 속성 참조 - user.first_name
      • user가 공유되고 변경 가능한 객체라면 first_name은 읽는 시점에 따라 값이 다를 수 있다.
    • 배열 참조 - stack [0]
      • stack이 공유되고 변경 가능한 배열이라면 첫 번째 항목은 읽는 시점에 따라 값이 다를 수 있다.
  • 상태
    • 값 할당 - z = 3;
      • 공유하기 위해 값을 할당했고 변경 가능한 변수라면 다르코 드에 영향을 주기 때문에 액션이다.
    • 속성 삭제 - delete user.first_name;
      • 속성을 지우는 것은 다른 코드에 영향을 주기 때문에 액션.

액션을 찾기 위해 액션 코드를 모두 찾을 필요는 없다. 단지 코드가 호출 시점이나 횟수에 의존하는지 생각을 해보면 된다.


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

  • 액션은 무엇인가?
    • 액션은 외부 세계에 영향을 주거나 받는 것을 말한다.
    • 그리고 액션은 실행 시점과 횟수에 의존한다.
      • 언제 실행되는지 - 순서
      • 얼마나 실행되는지 - 반복
    • 액션은 어떻게 구현하나?
      • 자바스크립트에서는 함수로 구현.
      • 계산도 함수로 구현하기 때문에 구분하기가 쉽지 않다.
    • 어떻게 액션에 의미를 담을 수 있나?
      • 액션으로 외부 세상에 영향을 줄 수 있다.
      • 액션의 예
        • 이메일 보내기
        • 계좌에서 인출하기
        • 전역 변숫값 바꾸기
        • ajax 요청 보내기
    • 액션은 일반적으로 무엇이라고 하나?
      • 다른 책에서 액션은 순수하지 않은 함수(impure function), 부수 효과가 있는 함수(function with side effects)라고 부른다.
      • 이 책에서는 액션이라고 부른다.
    • 액션은 쉽지 않다.
      • 액션은 다루기 힘들다.
      • 액션은 우리가 소프트웨어를 실행하려는 가장 중요한 이유이다.
      • 액션을 잘 사용하기 위한 방법
        1. 가능한 액션을 적게 사용한다
        2. 액션은 가능한 작게 만든다.
        3. 액션이 외부 세계와 상호작용하는 것을 제한할 수 있다.
          액션은 외부 세계에 영향을 주거나 받을 수 있다.
        4. 액션이 호출 시점에 의존하는 것을 제한한다.

요점 정리

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

[ 출처 : 쏙쏙 들어오는 함수형 코딩 ]

728x90