먼저 함수형 프로그래밍이란?
자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임의 하나이며, 함수를 이용하여 프로그래밍을 하는 것이다.
함수형 프로그래밍은 대입문이 없어 변수에 값이 할당되면 그 이후 절대 변하지 않는다.
좀 더 일반적으로 말하면, 함수형 프로그램은 부수 효과가 전혀 없다.
표현식: 함수들의 조합이라 생각하자.
결과를 바꿀 수 있는 부수 효과가 없기 때문에 그 표현식은 아무때나 실행될 수 있다.
표현식으로 인해 프로그래머들의 짐을 덜어준다.
표현식은 아무대나 실행될 수 있기 때문에 변수를 그 표현식의 값으로 대체할 수 있고, 값을 그 표현식으로도 대체할 수도 있다.
함수형 프로그래밍에도 다음과 같은 테크닉들을 사용한다.
- 일급 함수
- 익명 함수
- 클로져
- 커링
- 게으른 평가
- 대수적 데이터 타입
중요한 것은 이러한 프로그래밍 언어가 함수형 프로그래밍을 만드는 것은 아니며, 얼마나 코드를 함수형 답게 작성하냐에 달려있다.
함수형 답게 작성하는 코드는 어떤 코드가 있을까?
함수형 프로그래밍을 공부하다보면, 부수 효과라는 말을 많이 듣고, 보게 된다.
부수효과 없는 프로그래밍은 무엇일까?
함수형 프로그래밍은 함수들의 조합으로 만들어지며, 각 함수들은 인자를 받고, 그에 따른 결과를 내놓을 뿐, 함수 내부적으로 어떠한 상태도 가지지 않는다.
함수 호출 시 입력하는 값과 그에 대한 결과 값만이 중요하다.
부수 효과가 없다는 것은 다음과 같은 의미를 지닌다.
- 변수를 사용하지 않는다.
- 어떤 함수에 특정 값을 입력하면 그에 따른 출력이 발생하며, 같은 갑을 입력하면 항상 그에 따른 출력도 같다.
- 콘솔 또는 어떤 디바이스에도 출력하지 않는다.
- 파일, 데이터베이스, 네트워크 어디에도 데이터를 쓰지 않는다.
- 예외가 발생하지 않는다.
다음의 코드를 보고 부수 효과가 맞는지 판단해보자
public static int plus(int a, int b) {
return a + b;
}
위 코드는 b = 0일 때, 예외가 발생하기 때문에 부수 효과가 없는 코드이다.
반면, 아래 코드는 결과값이 이상하겠지만, 예외가 발생하지 않고 같은 입력에 항상 같은 값을 출력하기에 부수 효과가 없는 코드이다.
public static int plus(int a, int b) {
return (int) (a + (float) b);
}
아래 코드는 log를 쓰고 있기에 당연히 부수 효과가 있는 코드이다.
public static int add(int a, int b) {
log(String.format("Adding %s and %s", a, b));
while (b > 0) {
a++;
b--;
}
log(String.format("Returning %s", a));
return a;
}
왜 함수형 프로그래밍이어야 할까?
동시성 프로그래밍
명령형 프로그래밍에서 멀티 스레드를 활용한 동시성 프로그래밍은 개발자들을 아주 힘들게 하는 것 중 하나다.
명령형 프로그래밍에서 이러한 문제가 발생하는 주 원인은 스레드 간에 공유되는 데이터나 상태 값이 변경 가능하기 때문이다.
하지만 함수형 프로그래밍에서는 사용하는 모든 데이터가 변경 불가능하고 함수는 부수 효과를 가지고 있지 않다.
여러 스레드가 동시에 공유 데이터에 접근하더라도 해당 데이터가 변경될 수 없기 때문에 동시성과 관련된 문제를 원천적으로 봉쇄한다.