Funcitional Programming (함수형 프로그래밍)
프로그래밍 패러다임
프로그래밍 패러다임은 프로그래머에게 프로그래밍의 관점을 갖게하고 결정하는 역할을 한다.
- 명령형 프로그래밍: 프로그래밍의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 방식
- 알고리즘을 명시하고 목표는 명시 안함
- 절차지향 프로그래밍: 수행되어야 할 연속적인 계산 과정을 포함하는 방식 (C, C++)
- 객체지향 프로그래밍: 객체들의 집합으로 프로그램의 상호작용을 표현 (C++, Java, C#)
- 선언형 프로그래밍: 어떤 방법으로 해야 하는지(How)를 나타내기보다 무엇(What)과 같은지를 설명하는 방식
- 알고리즘은 명시하지 않고 목표만 명시
- 함수형 프로그래밍: 순수 함수를 조합하고 소프트웨어를 만드는 방식 (클로저, 하스켈, 리스프)
거의 모든 것을 순수 함수로 나누어 문제를 해결하는 기법으로, 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 해준다
유명한 책인 클린 코드(Clean Code)의 저자 Robert C.Martin은 함수형 프로그래밍을 대입문이 없는 프로그래밍이라고 정의하였다.
Functional Programming is programming without assignment satements
함수형 프로그래밍의 컨셉
- 변경 가능한 상태를 불변상태로 만들어 sideEffect를 없애자.
- 모든 것은 객체이다.
- 코드를 간결하고 가독성을 높여 구현할 로직에 집중 시키자
- 동시성 작업을 보다 안전하게 구현하자.
변경 가능한 상태를 불변상태(Immutable)로 만들어 SideEffect를 없애자.
함수 안에서 상태를 관리하고 상태에 따라서 결과값이 달라지면 안된다.
상태를 사용하지 않음으로 SideEffect를 사전에 차단할 수 있음.
또 변수 보다는 상수를 사용해 SideEffect를 차단함.
def f1(x : Int, y : Int) : Int{
x + y
}
def f2(x : Int, y : Int) : Int{
if(state == 1)
x + y
else
x - y
}
모든 것은 객체이다.
함수형 언어에서는 모든 것이 객체임.
코드를 간결하게 하고 가독성을 높여 로직에 집중 시키자.
Lambda 및 Collection, Stream 과 같은 API를 통해 보일러 플레이트를 제거하고, 내부에 직접적인 함수 호출을 통해 가독성을 높일수 있음. 일을 위한 일들이 줄어들어 실제 구현할 로직에만 집중 할 수 있게 됨.
//Java
view.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
List listA = new ArrayList<Integer>();
for(int i = 0; i<list.size(); i++) {
if(list.get(i) > 0)
listA.add(list.get(i)*2);
}
view.show(listA);
}
}
//Kotlin
view.setOnClickListener{
view -> {
view.show(list.filter( it > 0 ).map( it * 2 ))
}
}
동시성 작업을 보다 쉽고 안전하게 구현하자.
위에 설명한 immutable한 값을 사용해 여러 스레드에서 접근하더라도 SideEffect를 발생시키지 않음. 또한 Lock, UnLock같은 보호 장치도 필요 없다.
1급 객체란 ?
아래의 3가지 조건을 충족하면 1급 객체라고 할 수 있다.
1. 변수나 데이터에 할당할 수 있어야 한다.
2. 객체의 인자로 넘길 수 있어야 한다.
3. 객체의 리턴값으로 리턴 할 수 있어야 한다.
고차함수
- 람다 계산법에서 만들어진 용어로 아래의 조건을 만족함
- 함수에 함수를 파라미터로 넘길 수 있다.
- 함수의 반환값으로 함수를 사용할 수 있다.
- 고차함수는 1급함수의 부분집합subset이다.
Side Effect
- 변수의 값이 변경됨
- 자료 구조를 제자리에서 수정함
- 객체의 필드값을 설정함
- 예외나 오류가 발생하며 실행이 중단됨
- 콘솔 또는 파일 IO가 발생함
이러한 Side Effect를 제거한 함수들을 순수 함수라고 부르며,
함수형 프로그래밍에서 사용하는 함수는 이러한 순수 함수들이다.
- Memory or IO의 관점에서 Side Effect가 없는 함수
- 함수의 실행이 외부에 영향을 끼치지 않는 함수.
순수 함수를 이용하면 다음과 같은 효과가 있다.
- 함수 자체가 독립적이며, Side Effect가 없어 Thread 안정성을 보장받을 수 있다.
- Thread 안정성을 보장받아 병렬 처리를 동기화 없이 진행할 수 있다.
함수형 프로그래밍에서 함수는 1급 객채로 취급받아, 함수를 파라미터로 넘기는 등의 작업이 가능한 것이다.
참조 투명성(Referntial Transparency)
명령형 프로그래밍과 함수형 프로그래밍에서 사용하는 함수는 부수효과의 유/무에 따라 차이가 있다.
그에 따라 함수가 참조에 투명한지 안한지에 나눠진다.
참조에 투명하다는 것은 어떠한 상태의 변화 없이 항상 동일한 결과를 반환하여 항상 동일하게 실행 결과를 예측 할 수 있다는 것을 의미함.
그리고 부작용을 제거하여 프로그램의 동작을 이해하고 예측을 용이하게 하는 것은 함수형 프로그래밍으로 개발하려는 핵심 동기중 하나이다.
그리고 이러한 부분인 병렬 처리 환경에서 개발할 때 Race Condition 경합에 대한 비용을 줄여준다.
값의 대입 없이 항상 동일한 실행에 대한 동일한 결과를 반환하기 때문이다.
https://mangkyu.tistory.com/111