> 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-10.md).

# 불변성

## 불변성

> 데이터 값이 생성된 이후 변경되지 않는 것을 의미한다.

### 중첩된 데이터 (nested data)

> **데이터 구조 안에 데이터 구조가 중첩으로 되있는 것을 중첩된 데이터**라고 한다.

* Ex:) 배열 안에 객체가 있는 경우 중첩된 데이터
* 이런 경우 객체가 배열에 **중첩** 되었다고 볼 수 있다.

### 깊이 중첩 (deeply nested)

> 중첩이 이어지는 것을 깊이 중첩이라 한다.

* 어떤 객체가 객체 안에 배열, 그 배열 안에 객체 이런 구조처럼 중첩은 계속 이어질 수 있다.
* **중첩된 모든 데이터 구조가 변하지 않아야 불변 데이터라고 볼 수 있다.**

## 동작을 읽기, 쓰기 또는 둘 다로 분류하기

### 읽기(Read)

> 데이터를 바꾸지 않고 정보를 꺼내는 것

* 데이터를 변경하지 않기 때문에 다루기 쉬움
* 인자에만 의존해 정보를 가져오는 읽기 동작은 **계산**이다.

{% hint style="info" %}
변경 가능한 데이터는 실행 시점(읽는 시점)에 따라 달라질 수 있으므로, **변경 가능한 데이터를 읽는 것은 액션이다.**
{% endhint %}

### 쓰기(Write)

> 쓰기 동작은 데이터를 바꾸기 때문에, 데이터를 변경 가능한 구조로 만든다.

* 쓰기 동작은 **불변성 원칙(copy-on-write)에 따라 구현**해야 한다.
* 자바스크립트는 기본적으로 변경 가능한 데이터 구조를 사용하기 때문에 불변성 원칙을 적용하기 위해서는 직접 구현해야 한다.&#x20;
* 쓰기를 모두 없앤다면 변경할 수 없는 값이 되므로, 불변 데이터가 된다

## 카피-온-라이트(copy-on-write)

> 데이터를 불변형으로 유지할 수 있는 원칙

* 복사본을 만들고 변경하는 것을 말함
* 값을 변경하기 전에 얕은 복사를 하고 반환한다. 이렇게하면 통제할 수 있는 범위에서 불변성을 구현할 수 있다.

### 원칙 3단계

1. 복사본 만들기
2. 복사본 변경하기
3. 복사본 반환하기

{% hint style="info" %}
카피-온-라이트 원칙은 데이터(원본)을 변경하지 않고 반환했기 때문에 읽기(Read)이다.

즉, 카피-온-라이트 원칙은 쓰기(Write) → 읽기(Read)로 바꾼다.

쓰기를 읽기로 바꾸면 코드에 계산이 많아진다.&#x20;

즉, 데이터 구조를 불변형으로 만들 수록 코드에 더 많은 계산이 생기고 액션은 줄어든다.
{% endhint %}

### 쓰기도 하면서 읽기도 하는 동작을 copy-on-write로 변경하기

* 읽고 변경하는 일을 동시에 하는 동작은 값을 변경하고 반환한다.&#x20;

```javascript
const nums = [1, 2, 3, 4];
const shiftNums = nums.shift(); // 1
console.log(shiftNums); // [2, 3, 4]
```

#### copy-on-write 원칙 적용

1. 읽기와 쓰기 함수로 각각 분리
2. 함수에서 값을 두개 리턴

```typescript
const lastElement = <T>(array: T[]) => array.at(-1);
const dropLast = <T>(array: T[]) => [...array.slice(0, array.length - 1)];

const pop = <T>(array: T[]) => ({last: lastElement(arrat), array: dropLast(array)});
```

## 불변 데이터의 진실

### 불변 데이터는 충분히 빠르다.

* 일반적으로 불변 데이터 구조는 변경 가능한 데이터 구조보다 메모리를 더 많이 쓰고 느리다.
* 불변 데이터 구조를 사용하면서 대용량 고성능 서비스를 구현하는 사례도 많이 있다. \
  즉, 불변 데이터도 일반 애플리케이션 서비스에서 쓰기 충분히 빠르다는 증거
* 가비지 컬렉터는 충분히 매우 빠름
* 생각보다 많이 복사하지 않는다. 얕은 복사(shallowd copy)는 중첩된 데이터 구조에서 최상위 단계만 복사한다. 내부 중첩된 데이터는 참조에 대한 복사본으로 같은 메모리를 가리키는데 이것을 **구조적 공유**라 한다.

### 언제든 최적화 가능

* 성능 최적화는 미리 하지 않는것이 국룰
* 불변 데이터를 사용하고 성능 부분에서 이슈가 생긴다면 그 때 최적화하자.

{% hint style="info" %}
**데이터가 모두 불변형이면 시간에 따라 변하는 애플리케이션 상태를  어떻게 다룰수 있는가?**

모든 값을 불변형으로 만들더라도 시간에 따라 바뀌는 값(최신값)을 다룰수 있어야 하는데 함수형 프로그래밍에서는 필요할 때 새로운 값으로 교체(swapping)하는 방법을 흔히 사용한다.
{% endhint %}
