> For the complete documentation index, see [llms.txt](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/fp/undefined-6.md).

# 액션과 계산, 데이터

{% hint style="info" %}
함수형 프로그래밍 기술에서 코드를 `액션`, `계산`, `데이터`로 구분하는 것은 중요한 개념이다.

함수형 프로그래밍 개발자는 액션 << 계산 << 데이터 순으로 선호한다.
{% endhint %}

## 액션

> 외부 세계에 영향을 주거나 받는 것

* 실행 시점과 횟수에 의존한다.
* 액션은 코드 전체로 퍼져나가는 특성이 있다.
  * 액션을 부르는 함수, 또 그 함수를 부르는 함수역시 액션이 된다.
  * 이런식으로 내부의 액션이 코드 전체로 퍼져나가기 때문에 가장 바깥쪽으로 격리시키는 것이 핵심
* **부수 효과가 있는 함수, 순수하지 않은 함수** 라고 부르기도 한다.
* 액션에서 모든 암묵적 입력과 출력을 없애지 않더라도 가능한 줄이면 좋다.
* 액션 안에는 계산과 데이터, 또 다른 액션이 숨어있을 수 있다.
* **코드의 많은 부분을 액션에서 계산으로 옮기면 결과적으로 액션도 다루기 쉬워진다.**

### 액션 유형

* 외부 동작을 제어하는 함수 ex:) `alert('hello world)`
* 호출 시점에 의존적인 생성자 ex): `new Date()`
* 참조 표현식 ex:) 변수 참조, 속성 참조, 배열 참조 등, 불변값이 아니란면 호출 읽는 시점에 달라질 수 있다.
* 상태 ex:) 공유하기 위해 값을 할당했고 변경 가능하다면 다른 코드에 영향을 주기 때문에 액션이된다.

{% hint style="info" %}
언제 호출하는지, 몇번을 호출하는지에 따라 결과가 달라진다면 **액션**이라고 보자.
{% endhint %}

### 액션을 잘 사용하는 방법

1. 우리가 만드려는 제품은 외부와의 상호작용이 필수이므로 액션을 배제할 수 없다. 가능한 액션을 적게 사용하고 액션 대신 계산을 사용할 수 없는지 고민해보자.
2. 액션에서 액션과 관련없는 코드는 모두 제거해서 가능한 작게 만들어야 한다. 계획과 관련된 부분은 계산으로 추출하자.
3. 내부에 계산과 데이터들로 이루고, 바깥 쪽에 액션만 있는 구조로 분리시키자. `어니언 아키텍처`
4. 액션이 호출시점과 횟수에 덜 의존적이게 만들어야 한다.

## 계산

> 입력값으로 출력값을 만드는 행위&#x20;

* 실행 시점과 횟수에 관계없이 항상 같은 입력값에 대해 같은 출력값을 반환한다.
* 외부에 영향을 끼치지 않는다.
* **순수 함수, 수학 함수**라고도 불린다.
* 함수형 프로그래밍의 대부분은 계산을 가지고 작업을 한다.
* 계산은 일반적으로 외부에 있는 액션을 통해 수행된다.
* 계산의 정의에 따르면 암묵적 입출력이 없어야 한다.
* 계산은 더 작은 계산과 데이터로 나누고, 연결할 수 있다.
  * 계산을 나누면 첫번째 계산의 결과가 두 번째 계산의 입력값이 된다.

{% hint style="info" %}
계산은 우리 머릿속에서 일어나고, 사고 과정에 녹아있기 때문에 계산 단계가 잘 보이지 않을 수 있다.
{% endhint %}

### 계산의 장점

* 입력에 따른 결과가 명확하기 때문에 테스트하기 용이하다.
* 계산을 조합해 더 큰 계산을 만드는 식으로 재사용성과 확장성이 좋다.
* 실행 시점이나, 횟수를 신경쓰지 않아도 된다.&#x20;

### 계산의 단점

* 계산과 액션은 실행하기전에 어떤 일이 발생할지 알 수 없다는 단점이 있다.
* 코드를 읽어나가면서 예측은 할 수 있겠지만 결국 입력값을 넣고 실행해야 결과를 알 수 있다.
* 이런 단점이 싫다면 **`데이터`**&#xB97C; 사용하자.

{% hint style="info" %}
**계산과 데이터의 차이는 실행 여부**에 있다.\
계산은 함수로 실행 가능하지만 데이터는 보이는 그대로 정적이므로 실행할 수 없다.\
단, 계산은 실행하기 전까지 어떻게 동작할지 알 수 없다.
{% endhint %}

## 데이터

> 데이터는 이벤트의 대한 사실이다. 즉, 일어난 일의 결과를 기록한 것

* 정적이고 데이터 자체로 의미가 있기 때문에 해석이 필요하다.
* 실행이 필요한 코드만큼 복잡하지 않기 때문에 다른것(액션, 계산)과 구분된다.
* **데이터를 언제나 쉽게 해석할 수 있도록 표현하는 것이 함수형 프로그래밍의 핵심 기술**
* 계산과 액션은 서로 비교하기 어렵지만, 데이터는 그 자체이므로 비교할 수 있다.
* 데이터는 여러가지 의미로 해석될 수 있다.
*

### 불변성(immutable)

> 함수형 프로그래머는 불변 데이터 구조를 만들기 위해 두 가지 원칙을 사용한다.
>
> 1. **카피-온-라이트(copy-on-write)**
> 2. **방어적 복사(defensive copy)**

#### 카피-온-라이트

* 데이터를 변경하기 전 복사본을 만들어 원본 대신 복사본을 변경하고 반환
* 무엇이 바뀌는지 알기 때문에 무엇을 복사해야 할지 예상 가능
* **얕은 복사(shallow copy)**&#xC774;기 때문에 최상위 객체만 복사되고, 중첩된 객체는 복사되지 않고 같은 데이터를 참조하게 된다. 이것을 **구조적 공유(structual sharing)**&#xC774;라 한다.

#### 방어적 복사

* 네이밍 그대로 외부에서 변경될 가능성이 있어 예측할 수 없는 데이터를 방어적으로 관리하고 사용하기 위함
* 신뢰할 수 없는 코드와 데이터를 주고 받을 때 사용
* **깊은 복사(deep copy)**&#xB97C; 사용하여 외부에서 들어올 때, 외부로 나갈 때 모두 깊은 복사본을 만들어야 한다.

### 데이터 단점

* 유연하게 해석될 수 있는 부분은 장점이지만, 해석이 반드시 필요하다는 점은 단점이다.
* 계산은 해석하지 않아도 실행할 수 있다.
* 해석하지 않은 데이터는 쓸모가 없다.

{% hint style="info" %}
함수형 프로그래밍의 일반적인 구현순서

1. 데이터
2. 계산
3. 액션
   {% endhint %}
