์์ฑ์ผ: 2019.12.13
์๋ฌธ Functional Programming for Android Developers — Part 2์ ๋ฒ์ญํ ๊ธ์ ๋๋ค.
์ด์ ํํธ์์ Purity, Side effects, Ordering์ ๋ํด ๋ฐฐ์ ๊ณ , ์ด๋ฒ ํํธ์์๋ immutability์ Concurrency์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. Part 1์ ์์ง ์ฝ์ง ์์๋ค๋ฉด, ์ฌ๊ธฐ์์ ํ์ธํ์ธ์.
Immutability
Immutability๋ ๊ฐ์ด ํ ๋ฒ ์์ฑ๋๋ฉด ์ ๋ ๋ฐ๋ ์ ์๋ค๋ ๊ฐ๋ ์ ๋๋ค.
์๋์ ๊ฐ์ Car ํด๋์ค๊ฐ ์์ต๋๋ค:
Java
public final class Car {
private String name;
public Car(final String name) {
this.name = name;
}
public void setName(final String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Kotlin
class Car(var name: String?)
Java ์ฝ๋์์๋ setter๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , Kotlin์์๋ name์ด ์์ ๊ฐ๋ฅํ ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ์์ฑ ํ Car์ ์ด๋ฆ์ ๋ฐ๊ฟ ์ ์์ต๋๋ค.
Java
Car car = new Car("BMW");
car.setName("Audi");
Kotlin
val car = Car("BMW")
car.name = "Audi"
์์ฑ ํ ์์ ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์ด ํด๋์ค๋ immutable์ด ์๋๋๋ค.
immutable๋ก ๋ง๋ค๊ธฐ ์ํด์๋ (Java ์ฝ๋์์):
- name ๋ณ์๋ฅผ final๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค.
- setter๋ฅผ ์ญ์ ํด์ผ ํฉ๋๋ค.
- ๋ค๋ฅธ ํด๋์ค์์ ์์๋ฐ์ ๋ด๋ถ๋ฅผ ์์ ํ ์ ์๋๋ก ํด๋์ค๋ final๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค.
Java
public final class Car {
private final String name;
public Car(final String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Kotlin์์๋ immutable ๋ณ์๋ก ์ ์ธ๋ง ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
Kotlin
class Car(val name: String)
์ด์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ์๋ ์์ง๋ง ํ ๋ฒ ์์ฑ๋๋ฉด ์๋ฌด๋ ์์ ํ ์ ์์ต๋๋ค. ์ด ํด๋์ค๋ ์ด์ immutable ํด๋์ค์ ๋๋ค.
ํ์ง๋ง Java์ getName() getter๋ Kotlin์ name ์ ๊ทผ์๋ ์ด๋จ๊น์? ํธ์ถํ ์ชฝ์ name ๋ณ์์ ๊ฐ์ ๋ง๊ฒ ๋ฐํํ ๊น์? ๋ง์ฝ ๋๊ตฐ๊ฐ ์ด getter๋ฅผ ํตํด ์ฐธ์กฐ๋ฅผ ์ป์ ํ name ๊ฐ์ ๋ฐ๊พธ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
Java์์๋ String์ ๊ธฐ๋ณธ์ ์ผ๋ก immutable ์ ๋๋ค. ๋๊ตฐ๊ฐ name์ ์ฐธ์กฐ๋ฅผ ์ป์ด ์์ ํ๋ฉด, name ๊ฐ์ ๋ณต์ฌํด์ ์ฌ์ฉํ๊ณ ์๋์ string์ ๊ทธ๋๋ก ๋จ์์์ต๋๋ค.
ํ์ง๋ง immutable์ด ์๋ List ๊ฐ์ ๋ค๋ฅธ ํ์ ๋ค์ ์ด๋ป๊ฒ ๋ ๊น์? Car ํด๋์ค๊ฐ Driver ๋ฆฌ์คํธ๋ฅผ ๊ฐ๋๋ก ์์ ํด๋ด ์๋ค.
Java
public final class Car {
private final List<String> listOfDrivers;
public Car(final List<String> listOfDrivers) {
this.listOfDrivers = listOfDrivers;
}
public List<String> getListOfDrivers() {
return listOfDrivers;
}
}
์ด ๊ฒฝ์ฐ์ ๋๊ตฐ๊ฐ getListOfDrivers()๋ฅผ ์ฌ์ฉํ์ฌ ์ฐธ์กฐ๋ฅผ ์ป์ด ๋ด๋ถ ๋ฆฌ์คํธ๋ฅผ ์์ ํ ์ ์๊ณ , ๋ฐ๋ผ์ ์ด ํด๋์ค๋ mutable์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
immutable๋ก ๋ง๋ค๊ธฐ ์ํด์๋, getter์์ ๋ด๋ถ์ ๋ฆฌ์คํธ์๋ ๋ณ๋์ธ deep copy๋ ๋ฆฌ์คํธ๋ฅผ ๋๊ฒจ์ ์๋ก์ด ๋ฆฌ์คํธ๊ฐ ํธ์ถ๋ ์ชฝ์์ ์์ ํ๊ฒ ์์ ๋ ์ ์๋๋ก ํด์ผ ํฉ๋๋ค. ์์ฑ์๋ฅผ ํตํด ๋ฐ์ ๋ฆฌ์คํธ ๋ํ deep copy๋ฅผ ํตํด Car ์์ฑ ํ์๋ ์ธ๋ถ์์ ์๋ฌด๋ ์์ ํ์ง ๋ชปํ๊ฒ ํด์ผ ํฉ๋๋ค.
Deep copy๋ ๊ฐ์ง๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ชจ๋ ๋ณต์ฌํ๋ค๋ ์๋ฏธ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฆฌ์คํธ๊ฐ ์ผ๋ฐ String์ด ์๋ Driver ๊ฐ์ฒด์ ๋ฆฌ์คํธ๋ผ๋ฉด, Driver๊ฐ์ฒด๋ ๊ฐ๊ฐ ๋ชจ๋ ๋ณต์ฌํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด mutableํ ์๋์ Driver ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ๋ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๊ฒ ๋ฉ๋๋ค. ์ด ํด๋์ค์์๋, ๋ฆฌ์คํธ๊ฐ ์ด๋ฏธ immutable์ธ String์ผ๋ก ๊ตฌ์ฑ๋๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด deep copy๋ฅผ ํ ์ ์์ต๋๋ค:
Java
public final class Car {
private final List<String> listOfDrivers;
public Car(final List<String> listOfDrivers) {
this.listOfDrivers = deepCopy(listOfDrivers);
}
public List<String> getListOfDrivers() {
return deepCopy(listOfDrivers);
}
private List<String> deepCopy(List<String> oldList) {
List<String> newList = new ArrayList<>();
for (String driver : oldList) {
newList.add(driver);
}
return newList;
}
}
์ด์ ์ด ํด๋์ค๋ ์ ๋ง๋ก immutable ํฉ๋๋ค.
Kotlin์์๋ ๊ฐ๋จํ๊ฒ ํด๋์ค์์ ๋ฆฌ์คํธ๋ฅผ immutable๋ก ์ ์ธํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉํ ๋๋ ์์ ํฉ๋๋ค(Java ์ฝ๋์์ ํธ์ถํ๋ ๋ฑ์ ์์ธ ์ํฉ๋ง ์์ผ๋ฉด์).
Kotlin
class Car(val listOfDrivers: List<String>)
Concurrency
Part 1์์ ์๊ธฐํ๋ ๊ฒ์ฒ๋ผ, ์์ ํจ์๋ concurrency๋ฅผ ์ฝ๊ฒ ๊ฐ๋ฅํ๋๋ก ํด์ฃผ๊ณ , ๊ฐ์ฒด๊ฐ immutable์ด๋ฉด ์์ ์ผ๋ก ์ธํ ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ํ๋ ์ผ์ด ์๊ธฐ ๋๋ฌธ์ ์์ ํจ์์์์ ์ฌ์ฉ์ด ๋งค์ฐ ์ฝ์ต๋๋ค.
์์๋ฅผ ๋ด ์๋ค. Car ํด๋์ค์ Java๋ getNoOfDrivers() ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ณ Kotlin์์๋ mutable ๋ณ์๋ฅผ ์ถ๊ฐํ์ฌ ์ธ๋ถ์์ driver์ ์๋ฅผ ์์ ํ ์ ์๋๋ก ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณด์ธ์:
Java
public class Car {
private int noOfDrivers;
public Car(final int noOfDrivers) {
this.noOfDrivers = noOfDrivers;
}
public int getNoOfDrivers() {
return noOfDrivers;
}
public void setNoOfDrivers(final int noOfDrivers) {
this.noOfDrivers = noOfDrivers;
}
}
Kotlin
class Car(var noOfDrivers: Int)
Car ์ธ์คํด์ค๋ฅผ Thread_1, Thread_2์ด๋ผ๋ ๋ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค. Thread_1์ Driver ์์ ๊ธฐ๋ฐํ ์ด๋ค ๊ณ์ฐ์ ํ๊ธฐ ์ํด Java์ noOfDrivers()๋ฅผ ํธ์ถํ๊ฑฐ๋ Kotlin์ noOfDrivers ํ๋กํผํฐ์ ์ ๊ทผํฉ๋๋ค. ์ด ๋ Thread_2๋ noOfDrivers ๋ณ์๋ฅผ ์์ ํ๋ ค๊ณ ํฉ๋๋ค. Thread_1์ ์ด๋ฐ ๋ณํ์ ๋ํด ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๊ฐ์ ๊ฐ์ ธ์์ ๊ณ์ฐํฉ๋๋ค. ์ด๋ฐ ๊ณ์ฐ๋ค์ ํ๋ฆด ์ ๋ฐ์ ์์ต๋๋ค.
์๋ ์ํ์ค ๋ค์ด์ด๊ทธ๋จ์ ์ด ์ด์๋ฅผ ๋ํ๋ ๋๋ค:
์ด๊ฑด Read-Modify-Write ๋ฌธ์ ๋ผ๊ณ ํ๋ ๊ธฐ๋ณธ์ ์ธ race condition์ ๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๊ณ ์ ์ ์ธ ๋ฐฉ๋ฒ์ locks์ mutexes๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๊ณต์ ๋ ๋ฐ์ดํฐ์ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์ ๊ทผํ๋๋ก ํ๊ณ , ํ ์ฐ์ฐ์ด ๋๋๋ฉด lock์ ํด์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค(์ฐ๋ฆฌ ์์ ์์๋, Thread_1์ด ๊ณ์ฐ์ ๋๋ผ ๋๊น์ง Car์ lock์ ๊ฑธ๊ณ ์๋ ๊ฒ๋๋ค).
์ด๋ฐ lock ๊ธฐ๋ฐ์ ์์ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ์์ ์ ์ผ๋ก ๋ง๋ค์ด ์์ฃผ ์ด๋ ต๊ณ , ๋ถ์ํ๊ธฐ๋ ๋งค์ฐ ํ๋ ๋์์ฑ ๋ฒ๊ทธ๊ฐ ์๊ธฐ๊ธฐ ์ฝ์ต๋๋ค. ๋ง์ ๊ฐ๋ฐ์๋ค์ด deadlock๊ณผ livelock ๋๋ฌธ์ ๋ฉ๋ถ์ด ์ค๊ณค ํ์ฃ .
immutability(๋ถ๋ณ์ฑ)๊ฐ ์ด๊ฑธ ์ด๋ป๊ฒ ํด๊ฒฐํด์ค ์ ์์๊น์? Car๋ฅผ immutable๋ก ๋ค์ ๋ง๋ค์ด ๋ด ์๋ค:
Java
public final class Car {
private final int noOfDrivers;
public Car(final int noOfDrivers) {
this.noOfDrivers = noOfDrivers;
}
public int getNoOfDrivers() {
return noOfDrivers;
}
}
Kotlin
class Car(val noOfDrivers: Int)
Thread_2๊ฐ Car ์ธ์คํด์ค๋ฅผ ์์ ํ ์ ์๋ค๋ ๊ฒ์ด ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์, Thread_1์ ์ด์ ๊ฑฑ์ ์์ด ๊ฐ์ ๊ฐ์ ธ์์ ๊ณ์ฐํ ์ ์์ต๋๋ค. Thread_2๊ฐ Car ์ธ์คํด์ค ์์ ์ ์ํ๋ฉด, ์์ ์ ์ํด ๋ณต์ฌํ์ฌ ์๋ก ๋ง๋ค ๊ฒ์ด๊ณ , Thread_1์ ์ ํ ์ํฅ๋ฐ์ง ์์ ๊ฒ์ ๋๋ค. lock์ด ํ์์์ต๋๋ค.
Immutability๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณต์ ๋ ๋ฐ์ดํฐ๊ฐ thread-safeํ๋ค๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค. ์์ ๋์ง ๋ง์์ผ ํ ๊ฒ๋ค์ ์์ ๋ ์ ์์ต๋๋ค.
์์ ๊ฐ๋ฅํ ์ ์ญ ๋ณ์๊ฐ ํ์ํ ๋ ์ด๋กํ์ฃ ?
์ค์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ๋, ๋ง์ ์ธ์คํด์ค์ ์์ ๊ฐ๋ฅํ ์ํ๋ค์ ๊ณต์ ํด์ผ ํฉ๋๋ค. noOfDrivers๋ฅผ ์ ๋ฐ์ดํธํ๊ณ , ๊ทธ ์ ๋ฐ์ดํธ๋ฅผ ์์คํ ์ ๋ฐ์ ๋ฐ์ํด์ผ ํ๋ ์๊ตฌ์ฌํญ์ด ๋ถ๋ช ์์ ์ ์์ต๋๋ค. ์ด ๋ฌธ์ ์ ๋ํด์๋ ๋ค์ ์ฑํฐ์ functional architecture๋ฅผ ๋ค๋ฃฐ ๋, ์ํ ๊ณ ๋ฆฝ์ ์ด์ฉํ๊ณ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์์คํ ๊ตฌ์์ผ๋ก ๋ชฐ์๋์ ์ฒ๋ฆฌํ ๊ฒ์ ๋๋ค.
Persistent data structures
Immutable ๊ฐ์ฒด๋ ์ข์ ๋ฐฉ๋ฒ์ด์ง๋ง, ์ ํ์์ด ์ฌ์ฉํ๋ค๋ฉด, ๊ฐ๋น์ง ์ฝ๋ ํฐ์ ๋ถํ๊ฐ ๋๊ณ ์ฑ๋ฅ ์ด์๊ฐ ์๊ธธ ์๋ ์์ต๋๋ค. Functional programming์ ๊ฐ์ฒด ์์ฑ์ ์ต์ํํ๋ฉด์ immutability๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ ํฉํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ์ ๊ณตํฉ๋๋ค. ์ด๋ฐ ๊ตฌ์กฐ๊ฐ Persistent Data Structures์ ๋๋ค.
Persistent Data Structure๋ ์์ ๋ ๋ ์์ ์ ์ด์ ๋ฒ์ ์ ํญ์ ์ ์งํฉ๋๋ค. ์ด๋ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ์ฐ์ฐ๋ค์ด (๋ช ์์ ์ผ๋ก) ๊ฐ์ ์๋ฆฌ์ ์ ๋ฐ์ดํธํ์ง ์๊ณ , ํญ์ ์ ๊ตฌ์กฐ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ํจ์จ์ ์ธ immutable์ด ๊ฐ๋ฅํฉ๋๋ค.
์๋์ ๊ฐ์ ๋จ์ด๋ค์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด์ผ ํ๋ค๊ณ ํด๋ด ์๋ค: reborn, rebate, realize, realizes, relief, red, redder.
๊ฐ๊ฐ์ ๋ชจ๋ ๋ฐ๋ก ์ ์ฅํ ์๋ ์์ง๋ง ํ์ ์ด์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐ๊ฒ ๋ฉ๋๋ค. ์์ธํ ๋ณด๋ฉด, ๋จ์ด์ ๊ฒน์น๋ ๊ธ์๋ค์ด ๋ง์ ๊ฑธ ์ ์ ์์ต๋๋ค. ๊ทธ๋ผ ์ด ๋จ์ด๋ค์ ์๋์ฒ๋ผ ํ๋์ ํธ๋ฆฌ(Trie) ๊ตฌ์กฐ๋ก ๋ํ๋ผ ์ ์์ต๋๋ค(๋ชจ๋ ํธ๋ฆฌ ๊ตฌ์กฐ๊ฐ ์๊ตฌ์ ์ด์ง ์์ง๋ง persistent data structure ๊ตฌํ์ ์ํด ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ ์ค ํ๋์ ๋๋ค):
Persistent Data Structure๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ์ ์ ์๋ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ ๋๋ค. ์๋ก์ด ๋จ์ด๊ฐ ์ถ๊ฐ๋๋ฉด, ์ ๋ ธ๋๋ฅผ ์์ฑํ๊ณ ์ ์ ํ ๊ณณ์ ์ฐ๊ฒฐํฉ๋๋ค. ์ด๋ค ๊ฐ์ฒด์์ ๋ ธ๋ ์ญ์ ๊ฐ ํ์ํ ๊ฒฝ์ฐ, ํด๋น ๊ฐ์ฒด์์ ์ฐธ์กฐ๋ง ์ ๊ฑฐํ ๋ฟ ์ค์ ๋ ธ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์์ด์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ด ๊ตฌ์กฐ๋ฅผ ์ฐธ์กฐํ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์ ๊ณ์ ์ธ ์ ์์ต๋๋ค.
์๋ฌด ๊ฐ์ฒด๋ ์ฐธ์กฐํ์ง ์๋๋ค๋ฉด GC๋ฅผ ํตํด ์ ์ฒด ๊ตฌ์กฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ธ ์ ์์ต๋๋ค.
Java์์ Persistent Data Structure๋ ๊ธฐ๋ณธ์ ์ธ ๊ฐ๋ ์ ์๋๋๋ค. Clojure๋ JVM์์ ์คํ๋๋ ํจ์ํ ์ธ์ด์ด๊ณ , Persistent Data Structure๋ฅผ ์ํ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ต๋๋ค. Android ์ฝ๋์์ Clojure์ statndard lib์ ์ง์ ์ธ ์ ์์ง๋ง ์ฉ๋๊ณผ ๋ฉ์๋ ์๊ฐ ์๋นํ ํฝ๋๋ค. ๋ ์ข์ ๋์์ ์ ๊ฐ ์ ์ ๋ฐ๊ฒฌํ PCollections๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. 427๊ฐ์ ๋ฉ์๋์ 48kb dex size๋ง์ผ๋ก, ์ถฉ๋ถํ ์ธ ์ ์์ต๋๋ค.
์์๋ก PCollections๋ฅผ ์ด์ฉํด persistent linked list๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ๋ ๋ฒ์ ๋๋ค:
Java
ConsPStack<String> list = ConsPStack.empty();
System.out.println(list); // []
ConsPStack<String> list2 = list.plus("hello");
System.out.println(list); // []
System.out.println(list2); // [hello]
ConsPStack<String> list3 = list2.plus("hi");
System.out.println(list); // []
System.out.println(list2); // [hello]
System.out.println(list3); // [hi, hello]
ConsPStack<String> list4 = list3.minus("hello");
System.out.println(list); // []
System.out.println(list2); // [hello]
System.out.println(list3); // [hi, hello]
System.out.println(list4); // [hi]
์ฌ๊ธฐ์ ๋ณผ ์ ์๋ฏ์ด ๋ฐ๋ก ์์ ๋๋ ๋ฆฌ์คํธ๋ ์๊ณ , ์์ ์ด ํ์ํ ๊ฒฝ์ฐ ๋ชจ๋ ์๋ก์ด ๋ณต์ฌ๋ณธ์ด ๋ฐํ๋ฉ๋๋ค.
PCollections๋ ๋ค์ํ use case์ ๋ง๊ฒ ๊ตฌํ๋ ํ์ค Persistent data structure๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ํ Java์ ํ์ค Collection ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ๊ฝค ํธํ๊ฒ ํธํ๋ฉ๋๋ค.
Kotlin์ ์ด๋ฏธ immutable collection์ด ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ง์๋๋, Kotlin์ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด ์ข์ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์๋ ๊ฒ๋๋ค.
Persistent data structures๋ ์์ฃผ ๊ด๋ฒ์ํ ์ฃผ์ ์ด๊ณ ์ด ์น์ ์์๋ ๋น์ฐ์ ์ผ๊ฐ๋ง ๋ค๋ค์ ๋ฟ์ ๋๋ค. ์ข ๋ ์๊ณ ์ถ์ผ์๋ค๋ฉด, Chris Okasaki’s Purely Functional Data Structures๋ฅผ ์์ ์ถ์ฒํฉ๋๋ค.
Summary
Immutability์ Purity๋ ์์ ์ฑ์๊ณ ๋์์ฑ์ ๊ฐ๋ ํ๋ก๊ทธ๋จ์ ์ง๋ ๋ฐ ์์ด ๊ฐ๋ ฅํ ์กฐํฉ์ ๋๋ค. ๋ค์ ํํธ์์๋ higher order functions์ closures์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.