함수형 프로그래밍을 한마디로 정리하면 다음과 같다.
모든 데이터가 불변성을 지녀 같은 입력에 대해 같은 출력이 보장되어 부수효과가 없는 순수 함수
한마디로 정리한 글 안에 함수형 프로그래밍에 대한 키워드가 다수 있다.
함수형 프로그래밍 대해 공부를 해보면 다음과 같은 키워드는 무조건 등장한다.
순수 함수, 참조 투명성, 부수 효과, 불변성, 지연 연산(lazy evaluation), 클로저... 등등
본문에서는 "순수 함수, 참조 투명성, 부수 효과"에 대해 다뤄볼 예정이며
키워드 설명에 앞서 함수형 프로그래밍 등장 배경에 대해 간단히 알아보자.
함수형 프로그래밍은 알론조 처치(Alonzo Church)가 1950년대에 고안한 패러다임이지만
대세가 되지 못하고 시간이 흘러 최근 주목받기 시작했다.
주목받기 시작한 첫 번째 이유로 하드웨어의 성장이 있다.
2000년대 이전까지는 단일 코어를 주로 사용하며 싱글 프로세스, 싱글 스레드로 프로그래밍을 했지만
성능이 한계에 다다르며 멀티 쓰레드, 멀티 코어가 등장하게 되었다.
기존 프로그래밍 방식으로는 멀티 스레드를 활용하는 동시성 프로그래밍이 힘들었다.
기존 방식으로는 스레드에서 공유되는 데이터나 상태가 변경 가능했기 때문이다.
하지만 함수형 프로그램밍에서는 모든 데이터가 불변성을 지니고 부수 효과를 가지지 않기 때문에
동시성 문제를 해결할 수 있었다.
이러한 장점으로 인해 멀티코어 프로세스 환경에서 함수형 프로그래밍은 강력한 패러다임으로 작용한다.
그럼 이제 함수형 프로그래밍의 키워드에 대해 다뤄보겠다.
순수 함수라함은 다음 조건을 만족해야 한다.
- 동일한 인자에 대해 항상 동일한 결과를 반환해야 한다. (= 참조 투명성)
- 함수 실행으로 인한 부수 효과가 없어야 한다.
순수 함수에 대해 설명을 들으러 왔는데 참조 투명성이라느니 부수 효과라느니
또 모르는 용어 투성이지 않은가.
우선 밑에 코드를 참고해 보자.
순수 함수(동일한 인자가 주어졌을 때 동일한 결과를 리턴하는 케이스):
public int sum(int a, int b) {
return a + b;
}
a가 1이고 b가 2일 때 sum() 메서드를 언제 어디서 호출해도 결과는 3이다.
동일한 인자가 주어졌을 때 상황에 따라 결과가 달라지는 케이스:
int c = 10; // 불변 값이 아님
public int sum(int a, int b) {
return a + b + c;
}
c값이 불변이 아니기 때문에 때에 따라 결과값이 달라질 수 있다.
함수 자체가 독립적이며 부수 효과가 없기 때문에 안정적인 스레드를 보장한다.
스레드가 안정적이기 때문에 병렬 처리를 동기화 없이 진행할 수 있다.
참조에 투명하다는 것은 말 그대로 함수를 실행해도 어떠한 상태 변화 없이 항상 동일한 결과를 반환하여
동일하게(투명하게) 실행 결과를 참조(예측)할 수 있다는 것을 의미한다.
“참조 투명성”은 또한 함수(또는 메서드)가 함수 외부의 영향을 받지 않는 것을 의미한다.
따라서 위에 예시로 적어둔 순수 함수가 참조 투명성이 있다고 할 수 있다.
🔖 중요
다른 말로 하면, 함수의 결과는 입력 파라미터에만 의존하고,
함수의 외부 세계인 입력 콘솔, 파일, 원격 URL, 데이터베이스, 파일 시스템 등에서 데이터를 읽지 않는다.
함수 외부의 값을 변경하거나, 외부 세계의 의존적이지 않은 코드를 가리켜 “참조 투명성 있다” 라고 말한다.
💡 참고:
부수 효과(side effect)가 있는 함수는 비순수 함수(non-pure function)라고 하고,
그와 반대로 부수 효과가 없는 함수는 순수 함수(pure function)라고 한다.
부수 효과는 side effect를 뜻한다.
즉 어떤 액션으로 인해 변화가 생긴 것을 의미하는데
순수 함수는 그 자체로 독립적이며 어디에도 의존적이지 않기 때문에 함수형 프로그래밍은 부수효과가 없다고 하는 것이다.
부수 효과는 주로 다음과 같은 액션으로 인해 발생한다.
함수형 프로그래밍 어려워잉..