선언형 프로그래밍은 어떤 방법(How)으로 동작하는지 나타내기 보다 무엇(What)을 하는지를 중점으로 하는 방법이다.
//코드1(명령형)
function addOne (arr) {
let results = [];
for(let i=0; i<arr.length; i+=1){
results.push(arr[i]+1);
}
return results;
}
먼저 코드 1을 보면,
addOne이라는 함수는 arr 배열을 파라미터로 받고 나서 result라는 새로운 배열을 선언한 뒤, 배열 arr의 원소들에 1을 더 해서 result 배열에 push한 다음 그 값을 리턴하는 함수이다.
이렇게 어떻게(How) 동작하는지 확실하게 알 수 있다. 근데 그러면 당연히 이렇게 하지 선언형은 어떤 걸 말하는거지? 궁금점이 생길 것이다.
//코드2(선언형)
function addOne (arr) {
return arr.map((i) => i+1);
}
코드 2를 보면,
단순히 javaScript의 내장형 함수로 바꿔 쓴게 선언형 프로그래밍이라고 생각이 들 수 있다.
하지만 여기서 중요한 건 내장형 함수로 바꾸면서 추사화가 되었다는 것이다.
즉, 선언형 프로그래밍에서 가장 중요한 점은 명령형 프로그래밍의 추상화라는 것이다.
위 코드를 보면 결국 어떤(What) 일이 일어나는지를 보여주지 어떻게(How) 원하는 결과를 만들어내느지는 중요하지 않다.
함수형 언어
수학적 함수를 조합하여 문제를 해결하는 언어
side effect가 발생하지 않도록 함수를 짜야 한다.
재귀 호출이 자주 이용된다.
병렬 처리에 유리하다.
종류 : LISP
논리형 언어
기호 논리학에 기반을 둔 언어로, 논리 문장을 이용하여 프로그램을 표현하고 계산한다.
반복문이나 선택문을 사용하지 않는다.
비절차적 언어이다.
종류 : PROLOG
웹 브라우저의 표준 문서인 하이퍼텍스트 문서를 만들기 위해 사용하는 언어
특별한 데이터 타입이 없고 변수 사용이 없다.
호환성이 좋고 사용이 편리하다.
LIS
PROLOG
XML
HASKELL
SQL
가독성과 재사용성이 좋고, 작동 순서를 구체적으로 작성하지 않아서 오류가 적다.
프로그램 동작을 변경하지 않고도 관련 값을 대체할 수 있다.
해당 언어에서 문제가 발생해도 다른 것에 영향을 주지 않는다.(참조 투명성)
함수형 프로그래밍은 선언형 프로그래밍의 일종으로 프로그램이 상태의 변화 없이 데이터 처리를 수학적 함수 계산으로 취급하고자 하는 패러다임이다.
순수 함수의 조합으로 프로그래밍하며 최종 Output이 발생할 수 있도록 순수 함수들을 엮어서 호출한다. 문이 아닌 식이나 선언으로 수행되는 선언형 프로그래밍 패러다임을 따르고 있다.
순수 함수
동일한 입력에는 항상 같은 값을 반환한다.
함수의 출력(return)은 오로지 그 함수에 입력된 값(input)에만 의존한다.
함수의 실행은 프로그램의 실행에 영향을 미치지 않아야 한다.Self-contained되어야 한다. 즉, side effect가 없다.Side effect가 없다는 의미는 오로지 출력(return) 만 수행한다는 의미이다.
불변성
Input의 Immutability을 유지해야 순수함수의 순수성 유지가 의미가 있다.
구조체를 Input에 넣었을 때와 클래스를 Input에 넣었을 때 불변성을 유지시키는 구조가 다르다. 구조체는 deep copy이기 때문에 함수 내에서 변경이 불가능하기 때문에 Input의 불변성을 고민하지 않아도 된다. 하지만 클래스는 swallow copy이기 때문에 함수 내에서 속성 변경이 가능하다. 이는 함수가 상태를 변경할 수 있는 여지를 주게 되므로 주의해야 한다.
참조의 투명성
함수의 순수성, 전달인자의 불변성을 유지하면 다음과 같은 참조의 투명성을 기대할 수 있다.
Avoid
함수형 프로그래밍에서 가장 피해야 하는 지점이다.
함수의 합성
원하는 Output을 위해 둘 이상의 재사용 가능한 순수 함수를 조합하는 과정을 말한다.
함수형 프로그램은 여러 작은 순수 함수들로 이루어져있기 때문에 이 함수들을 연쇄적으로 또는 병렬로 호출해서 더 큰 함수를 만드는 과정으로 전체 프로그램을 구축한다. 그리고 이 과정에서 함수를 엮기 때문에 고차원함수(Higher-Order Functions)를 활용해야 한다.
이 때문에 함수형 프로그래밍에서 함수는 일급객체여야 한다.
swift에서는 filter, map, flatMap, reduce 등의 기능을 사용할 수 있다.
Function Decoration
Partial Application & Curring
// Partial Application
func add(_ a: Int, _ b: Int) -> (Int) -> Int {
return { c in
return a + b + c
}
}
var addTenFive = add(10, 5)//10과 5를 미리 합쳐준다!
print(addTenFive(5)) // 미리 10과 5가 합쳐줬기 때문에 20이 나온다.
//Curring
func before(_ a: String) -> ((String)->String) {
return { b in
return a + b;
}
}
var word = before("이렇게");
var finalWord = word("붙어요!");
print(finalWord); //이렇게붙어요!