- 자료 처리를 수학적 함수의 계산으로 취급하고
- 상태와 가변 데이터를 멀리하며
- 문제를 step by step 이 아닌 divide and conquer 로 해결하는 방식
- 기존 Factorial
var result = 1
for i in 1...n {
result *= i
}
- FP Factorial
fac n = foldr (*) 1 [1..n]
-- | f x [y1,y2..yk] = f y1 (f y2 (... (f yk x) ...))
- 기존 Persons
var persons: [Person] = []
for name in names {
let person = Person(name: name)
if person.isValid {
persons.append(person)
}
}
- FP Persons
let persons = names
.map(Person.init)
.filter { $0.isValid }
- pure function 를 조합한다
- 같은 입력이 주어지면 항상 같은 출력을 반환한다.
- 즉 코드 내부에 '숨겨진 입력'이나 '숨겨진 출력'이 없다.
- 테스트할 때 편리함
- shared state 를 피한다.
- shared state 의 문제점: history 를 전부 알아야 한다 / 호출 순서에 따라 결과가 달라질 수 있다
- mutable data 를 피한다.
- const 는 불변 객체를 만들지 않는다. 바인딩이 참조하는 객체를 변경할 수는 없지만, 여전히 객체의 속성은 변경 가능하다.
const a = Object.freeze({
foo: { greeting: "Hello"},
bar: 'world'
});
a.foo.greeting = 'Goodbye';
console.log(`${a.foo.greeting}, ${a.bar}${a.baz}`); // Goodbye, world!
- side effects 를 피한다.
- 반환값 이외에 함수 밖에서 관찰할 수 있는 앱의 상태 변화. ex) 콘솔 로깅, 파일에 쓰기, 네트워크에 쓰기, side effect 가 있는 다른 함수 호출.
- let 으로 지정한 변수의 경우 속성도 변경 불가능
- 함수의 parameter 로 들어온 변수는 변경 불가능한 게 default
- FP의 특징이라고 할 수 있는 Higher Order Function 이 있다 (filter, map, reduce)
- First Class: can be assigned to values and passed in and out
- Higher Order: can be accepted as parameters or used as return value
- 하지만 function unit 이 아닌 type unit 의 composition 을 한다. (ex. struct, enum)
- 그리고 type 에 context 정보가 들어간다. (ex. optional)
기존 예제
func login(username: String, password: String,
completion: (String?, Error?) -> Void)
login(username: "rob", password: "s3cret") {
(token, error) in
if let token = token {
// success
} else if let error = error {
// failure
}
}
수정 버전
struct Token {
let string: String
}
struct Credential {
var username: String
var password: String
}
enum Result<Value> {
case success(Value)
case failure(Error)
}
func login(credential: Credential,
completion: (Result<Token>) -> Void)
login(credential: credential) { result in
switch result {
case .success(let token): // success
case .failure(let error): // failure
}
}
- OOP 는 feature 개수가 fixed 이고 class 개수는 계속 늘어날 예정일 때
- FP 는 class 개수는 fixed 인데 feature 개수는 계속 늘어날 예정일 때