조컴퓨터

챕터 2. 현실에서의 함수형 사고 본문

책읽기/쏙쏙 들어오는 함수형 코딩

챕터 2. 현실에서의 함수형 사고

챠오위 2022. 8. 7. 00:20

챕터 2에서 중점적으로 볼 내용은 ?

- 현실적인 문제에 함수형 사고를 적용

- 소프트웨어의 구조를 잡는데 왜 함수형 프로그래밍이 좋은지

- 액션을 타임라인으로 구조화

- 타임라인을 활용하면 시간에 대한 문제를 잘 풀 수 있음

 

 

토니 피자에 오신 것을 환영합니다.

피자 가게를 운영하는 토니는 로봇에 함수형 사고를 사용했다.

다음은 두 가지 함수형 사고의 기술을 다시 한 번 살펴본 내용이다. 토니가 적용한 것을 통해 알아보자.

 

1. 액션과 계산, 데이터

   - 토니는 요리 재료와 기타 필요 자원을 사용하는 코드를 액션으로 구분하고, 나머지 코드는 계산과 데이터로 구분했다.

   - 코드에 적용한 계층형 설계(stratified design) 원칙이 무엇인지 알아보기

2. 일급 추상

   - 가게 주방에 많은 로봇들이 피자를 만들고 있는 상황을 분산 시스템이라 볼 수 있다.

   - 이때 토니는 가끔 실패하는 분산 시스템을 이해하려고 타임라인 다이어그램(timeline diagram) 을 사용한다.

   - 토니는 여러 로봇이 협력할 수 있도록 함수를 인자로 받는 일급 함수(first-class function) 를 사용한다.

 

 

파트 1: 액션과 계산, 데이터

1. 액션

   - 호출 횟수와 시점에 의존한다.

   - 액션을 사용할 때는 조심해야 한다.

2. 계산

   - 어떤 것을 결정하거나 계획하는 것이다.

   - 계산은 실행해도 외부에 영향을 주지 않는다.

3. 데이터

   - 변경 불가능하다.

   - 데이터는 유연하기 때문에 다양하게 쓸 수 있다.

 

 

변경 가능성에 따라 코드 나누기

계층화 설계 맛보기

변경 가능성에 따라 코드를 다음과 같이 나눌 수 있다. 토니의 코드를 예로 위쪽으로 갈수록 자주 바뀌는 코드가 있고 아래쪽으로 갈수록 자주 변하지 않는 코드이다.

함수형 코드 계층화 설계의 예시

각 계층은 그 아래에 있는 계층 기반으로 만들어 진다. 그래서 각 계층에 있는 코드는 더 안정적인 기반 위에 작성할 수 있다. 이런 구조로 소프트웨어를 만들면 코드를 쉽게 변경할 수도 있다. 가장 위에 있는 코드는 의존성이 거의 없기 때문에 쉽게 바꿀 수 있다. 아래에 있는 코드들은 위에 있는 코드보다 의존성이 많아 바꾸기 어렵지만 자주 바뀌지 않는다.

 

함수형 프로그래머는 이 아키텍쳐 패턴이 계층을 만들기 때문에 계층형 설계(stratified design) 라 부른다. 계층형 설계는 일반적으로 비즈니스 규칙, 도메인 규칙, 기술 스택 계층으로 나눈다.

 

계층형 설계로 만든 코드는 테스트, 재사용, 유지보수가 쉽다.

 

 

파트 2: 일급 추상

주방을 자동화하기

주문 접수

→ 도우 만들기 → 도우 펴기 (준비하고 사용하고)

→ 소스 만들기 → 소스 뿌리기 (준비하고 사용하고)

→ 치즈 갈기 → 치즈 뿌리기 (준비하고 사용하고)

→ 오븐에 넣기 → 10분 기다리기 → 서빙

 

위의 타임라인 다이어그램을 사용하면 액션이 시간 순서에 따라 어떻게 실행되는지를 확인할 수 있다. 액션은 실행 시점에 의존하기 때문에 실행 순서가 중요하다. 이보다 더 효율적으로 만들어 보자.

 

 

분산 시스템을 타임라인으로 시각화하기

토니의 피자집은 지금 한 대의 로봇으로 피자를 만들고 있기 때문에 속도가 빠르지 않다. 두 대를 추가하자.

 

여러 대의 로봇이 함께 일을 하는 것은 분산 시스템을 의미한다. 분산 시스템에서 독립된 액션의 실행 순서는 어떻게 될지 모른다. 토니는 타임라인 다이어그램을 다시 그려 로봇이 프로그래밍한 대로 동작을 하는지 알아보자. 

 

타임라인 다이어그램은 문제를 파악하는데 도움을 주지만 실행 순서가 섞이는 것을 어떻게 하지는 못한다. 토니는 이날 로봇 세 대로 장사를 해봤지만 완전히 실패했다. 많은 피자가 순서가 꼬여 잘못 만들어진 피자가 나왔다. 

 

 

각각의 타임라인은 다른 순서로 실행됩니다

기본적으로 타임라인은 서로 순서를 맞출 수 있는 기능이 없어서 순서대로 다음 작업을 진행시켜 버린다. 예를 들어, 소스가 먼저 완성되고 도우가 완성될 수 있다. 이 경우 소스를 만드는 로봇은 도우가 완성되기도 전에 도우 펴는 작업을 진행할 수도 있다. 

 

타임라인을 서로 맞추지 않은 분산 시스템은 예측 불가능한 순서로 실행된다. 도우, 소스, 치즈가 준비가 끝난 다음 피자를 만들어야 한다.

 

 

어려운 경험을 통해 분산 시스템에 대해 배운 것

1. 기본적으로 타임라인은 서로 순서를 맞추지 않는다.

  → 타임라인은 반드시 서로 실행 순서를 맞춰야 한다. 

2. 액션이 실행되는 시간은 중요하지 않다. 

  → 각각의 타임라인은 다른 타임라인의 순서와 관계없이 만들어야 한다. 

3. 드물지만 타이밍이 어긋나는 경우는 실제 일어난다. 

  → 타임라인은 항상 올바른 결과를 보장해야 한다. 

4. 타임라인 다이어그램으로 시스템의 문제를 알 수 있다.

  시스템을 잘 이해할 수 있다. 

 

 

타임라인 커팅 :  로봇이 서로를 기다릴 수 있게 하기

타임라인 커팅(cutting) 은 여러 타임라인이 동시에 진행될 때 서로 순서를 맞추는 방법이다.

 

타임라인은 고차 동작(high-order operation) 으로 구현한다. 각 타임라인은 독립적으로 동작하고 작업이 완료되면 다른 타임라인 끝나기를 기다리기 때문에 어떤 타임라인이 먼저 끝나도 괜찮다. 

 

 

좋은 경험을 통해 타임라인에 대해 배운 것

1. 타임라인 커팅으로 서로 다른 작업들을 쉽게 이해할 수 있다.

  → 타임라인에 컷을 그려 동시에 할 수 있는 재료 준비와 순서대로 해야 하는 피자 만들기를 분리했다.

2. 타임라인 다이어그램을 사용하면 시간에 따라 진행하는 작업을 쉽게 이해할 수 있다.

  → 동작 방법에 대해 확실할 수 있고, 동시에 실행되는 분산 시스템을 시각화하기에 좋다.

3. 타임라인 다이어그램은 유연하다.

  → 타임라인 다이어그램으로 동시에 진행되는 작업을 쉽게 모델링할 수 있다. 

 

 

 

출처 : 쏙쏙 들어오는 함수형 코딩(Grokking Simplicity: Taming complex software with functional thinking)