\(@^0^@)/

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

BOOKS/Grokking simplicity 함수형 코딩

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

minjuuu 2022. 7. 25. 20:46
728x90
  • 많은 함수형 프로그래밍 자료에서 함수형 프로그래밍은 부수 효과가 없는 순수한 함수로 프로그래밍을 해야 한다고 말한다.
  • 함수형 프로그래밍을 하려면 부수 효과를 처리하는 방법을 알아야 한다.
    • 부수 효과를 처리한다는 말은, 없앨 수 있는 부수 효과는 없애고 필요한 부수 효과는 잘 두는 것을 의미한다.

함수형 프로그래밍의 핵심 개념

  1. 계산과 액션을 구분하는 것
    • 계산은 외부에 어떤 영향을 주지 않기 때문에 여러 번 실행해도 같은 결과를 돌려준다.
    • 하지만 액션은 부수 효과를 가지고 있다.
      화면에 글씨를 표시하거나 로켓을 발사하는 것과 같은 액션은 실행할 때마다 다른 결과가 나올 수 있다.  
    • 코드에 어떤 부분에 부수 효과가 있고 어떤 부분이 '순수한 계산' 인지 쉽게 구분할 수 있는 패턴으로 구성하면 프로그램을 쉽게 이해할 수 있다.
  2. 배열, 리스트, 데이터베이스와 같은 컬렉션을 하나씩 처리하지 않고 '한 번에' 처리하는 것
    • '한 번에' 처리하기 위해서는 컬렉션 항목에 외부에 영향을 주는 부수 효과가 없어야 한다.
    • 항목이 독립적일 때 가장 효과적이다.
    • 이 개념은 첫 번째 개념인 계산과 액션의 구분이 있어야 동작하는 개념

함수형 프로그래밍은(functional programming) 무엇인가?

1. 수학 함수를 사용하고 부수 효과(side effect)를 피하는 것이 특징인 프로그래밍 패러다임
2. 부수 효과 없이 순수 함수(pure function)만 사용하는 프로그래밍 스타일

부수 효과는 함수가 리턴 값(결괏값) 이외에 하는 모든 일을 말한다.
(예를 들어 메일 보내기, 파일 읽기, 불빛을 깜박이기, 웹 요청하기, 자동차 브레이크 밟기, 전역 상태 수정하기)
부수 효과는 함수를 부를 때마다 발생하기 때문에 문제가 될 수 있다.
어떤 경우에는 리턴 값이 필요해서 불렀지만 의도하지 않게 부수 효과가 발생할 수 있다.
따라서 대부분의 함수형 프로그래머는 불필요한 부수 효과를 가능한 사용하지 않으려고 한다.
순수 함수는 부수 효과 없이 리턴 값(결괏값)이 인자에만 의존하는 함수를 말한다.
인자에만 의존한다는 말은 같은 인자를 넣으면 항상 같은 결과를 돌려준다는 말.
수학에서 함수도 그렇게 동작하기 때문에 우리는 순수 함수를 수학 함수라고 볼 수 있다.
순수 함수는 다루기 쉽고 이해하기 쉽기 때문에 함수형 프로그래머들이 중요하게 생각한다.

정의에 따르면 함수형 프로그래머는  항상 부수 효과를 피하고 순수 함수만을 사용해야 할 것 같지만, 실제 함수형 프로그래머는 부수 효과와 순수하지 않은 함수를 사용한다.


실용적인 측면에서 함수형 프로그래밍 정의의 문제점

문제 1 : 부수 효과는 필요하다.

부수 효과는 소프트웨어를 실행하는 이유이다. 따라서 필요할 때는 사용해야 한다.

문제 2 : 함수형 프로그래밍은 부수 효과를 잘 다룰 수 있다.

함수형 프로그래머는 부수 효과가 실제로 필요하지만 문제가 될 수 있다는 것을 알기 때문에 부수 효과를 잘 다루기 위한 도구를 많이 알고 있다.
또한 함수형 프로그래머는 순수하지 않은 함수도 사용하고 순수하지 않은 함수를 잘 다룰 수 있는 기술이 많이 있다.

문제 3 : 함수형 프로그래밍은 실용적이다.


액션과 계산, 데이터 구분하기

함수형 프로그래머는 직감적으로 코드를 세 분류로 나눈다.
많은 함수형 프로그래밍 기술과 개념은 코드를 액션, 계산, 데이터로 구분하는 것으로부터 시작한다.

  1. 액션 : 부르는 시점에 의존
    ex) 이메일을 보내는 코드, 데이터베이스에 저장하는 코드, 호출할 때마다 다른 시간을 주는 코드
  2. 계산 : 입력값을 계산해 출력하는 것
    ex) 모든 숫자를 더하는 함수, 같은 문자열을 넣으면 항상 같은 길이를 주는 함수
  3. 데이터 : 이벤트에 대한 사실을 기록한 것
    ex) 사람에 대한 정보, 숫자 리스트

액션은 호출하는 시점과 횟수에 의존하기 때문에 호출할 때 조심해야 한다.
계산이나 데이터는 둘 다 부르는 시점이나 횟수가 중요하지 않다. 계산과 데이터의 차이는 실행 여부에 있는데, 계산은 실행 가능하나 데이터는 그렇지 않다.
데이터는 정적이고 보이는 그대로이지만, 계산은 실행하기 전까지 어떻게 동작할지 알 수 없다.

액션과 계산, 데이터는 각각 장단점을 가지고 있기 때문에 잘 알고 적절하게 쓰는 것이 좋다.
일반적으로 액션보다는 계산이 쓰기 쉽고 계산보다는 데이터가 쓰기 쉽다고 생각한다. 결과적으로 가장 쓰기 좋은 것은 데이터이다.

조금 더 자세히 알아보자. 프로젝트 관리를 위해 클라우드 서비스를 만든다고 가정해보자.
여러 클라이언트가 작업 완료 표시를 하면 서버에서 이메일을 통해 알려주는 서비스에서 액션, 계산 그리고 데이터의 동작을 구분해보자.

  • 1단계 : 사용자가 작업 완료 표시를 함
    • 이것은 UI 이벤트이지만 실행 횟수에 의존하기 때문에 액션이다.
  • 2단계 : 클라이언트가 서버로 메시지를 보냄
    • 메시지를 보내는 것도 액션이다.
      그리고 메시지 자체는 나중에 서버에서 해석해야 하는 데이터이다.
  • 3단계 : 서버가 메시지를 받음
    • 메시지를 받는 것은 횟수에 의존하므로 액션이다.
  • 4단계 : 서버가 데이터베이스를 변경
    • 내부 상태를 바꾸는 것은 액션이다.
  • 5단계 : 서버가 누구에게 알람을 보낼지 결정
    • 결정하는 것은 계산이다.
      입력값이 같다면 서버는 항상 같은 결정을 내리기 때문
  • 6단계 : 서버가 이메일로 알림을 보냄
    • 이메일 보내기는 액션이다.
      같은 메일을 한 번 보내는 것과 두 번 보내는 것은 다르다.

함수형 프로그래밍에서는 코드를 세 가지로 분류한다.

1. 액션

액션은 실행 시점이나  횟수 또는 둘 다에 의존한다.
긴급한 메일을 오늘 보내는 것과 다음 주에 보내는 것은 완전히 다르다.
같은 메일을 10번 보내는 것과 한 번 보내는 것 또는 보내지 않는 것 역시 다르다.

  • 시간이 지남에 따라 안전하게 상태를 바꿀 수 있는 방법
  • 순서를 보장하는 방법
  • 액션이 정확히 한 번만 실행되게 보장하는 방법

2. 계산

계산은 입력값으로 출력 값을 만드는 것이다. 같은 입력값을 가지고 계산하면 항상 같은 결괏값이 나온다.
언제, 어디서 계산해도 결과는 같고 외부에 영향을 주지 않는다. 계산은 테스트하기 쉽고 언제든지 몇 번을 불러도 안전하다.

  • 정확성을 위한 정적 분석
  • 소프트웨어에서 쓸  수 있는 수학적 지식
  • 테스트 전략

3. 데이터

데이터는 이벤트에 대해 기록한 사실이다. 데이터는 실행하는 코드만큼 복잡하지 않기 때문에 다른 것과 구분이 된다.
알아보기 쉬운 속성으로 되어 있고 실행하지 않아도 데이터 자체로 의미가 있다.
또 같은 데이터를 여러 형태로 해석할 수 있다.
ex) 레스토랑의 영수증 데이터 : 관리자의 경우 인기 있는 메뉴를 알아보기 위해, 고객은 외식비 지출 내역을 위해.

  • 효율적으로 접근하기 위해 데이터를 구성하는 방법
  • 데이터를 보관하기 위한 기술
  • 데이터를 이용해 중요한 것을 발견하는 원칙

액션, 계산, 데이터를 구분하면 어떤 장점이 있을까?

여러 컴퓨터가 네트워크를 통해 통신하기 시작하면 소프트웨어가 복잡해진다.
처리해야 할 메시지는 순서가 섞일 수 있고 중복되기도 하고 유실되기도 한다.
시간에 따라 바뀌는 값을 모델링할 때 동작 방법을 이해하는 것은 중요하지만 쉽지 않다.

실행 시점이나 횟수에 의존하는 코드를 없애면, 코드를 더 쉽게 이해할 수 있고 심각한 버그를 막을 수 있다.
데이터와 계산은 실행 시점이나 횟수에 의존하지 않는다.
그래서 코드를 데이터와 계산으로 바꿀수록 분산 시스템에서 생기는 여러 가지 문제를 해결할 수 있다.
액션은 실행 시점과 횟수에 의존하기 때문에 여전히 문제가 되지만, 코드 전체에 영향을 주지 않도록 격리시키면 된다.
또 분산 시스템이 아무리 불확실성을 가지고 있다고 해도 액션을 안전하게 다룰 수 있는 기술이 있기 때문에 안심할 수 있다. 또한 코드의 많은 부분을 액션에서 계산으로 옮기면 결과적으로 액션도 다루기 쉬워진다.

분산 시스템 규칙 3가지

  • 메시지 순서가 바뀔 수 있다.
  • 메시지는 한 번 이상 도착할 수 있고 도착하지 않을 수도 있다.
  • 응답을 받지 못하면 무슨 일이 생겼는지 알 수 없다.

함수형 사고는 무엇인가?

함수형 사고는 함수형 프로그래머가 소프트웨어 문제를 해결하기 위해 사용하는 기술과 생각을 말한다.
함수형 프로그래밍에서 가장 중요하다고 생각하는 두 가지 개념들 중 첫 번째는 액션과 계산, 데이터를 구분해서 생각하는 것이고, 두 번째는 일급 추상(frist-class abstraction)이라는 개념이다.
이 두 가지 개념은 함수형 프로그래밍으로 실용적이고 튼튼한 프로그램을 만드는 기초가 된다.
즉, 이 개념을 이해하는 것이 전문적인 함수형 프로그래머로 가는 길이라고 할 수 있다.


정리

  • 함수형 사고는 함수형 프로그래밍의 기술과 개념을 말한다.
  • 함수형 프로그래머는 코드를 액션과 계산, 데이터로 나눠서 바라본다.
  • 액션은 시간에 의존한다. 그래서 사용하기 가장 어렵다. 액션에서 시간에 의존하는 부분을 분리하면 좀 더 다루기 쉽다.
  • 계산은 시간에 의존적이지 않다. 다루기 쉽기 때문에 가능한 코드를 계산으로 바꾸는 것이 좋다.
  • 데이터는 정적이고 해석이 필요하다. 데이터는 저장하거나 이해하기 쉽고 전송하기 편리하다.

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

728x90