함수형 프로그래밍이 중요하다는 이야기가 자주 들려오고 있다. 그런데 이 함수형 프로그래밍, 함수형 언어가 무엇인지에 대해 구글에 검색해보아도 속 시원히 알기가 어렵다. 이 언어가 무엇인지, 왜 중요한 건지, 어떤 프로젝트를 할 때 활용할 수 있는 개념인지 알아야 나중에 사용할 수 있을텐데 이해조차 되지 않으니 답답한 마음이 든다.
이에 포스팅을 하면서 함수형 프로그래밍 언어에 대해 차근차근히 알아보고자 한다.
함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임 중 하나이다.
명령형 프로그래밍에서 상태를 바꾸는 것을 강조하는 것과는 달리, 함수형 프로그래밍은 함수의 응용을 강조한다. 또한 함수형 프로그래밍은, 프로그래밍이 문이 아닌 식이나 선언으로 수행되는 선언형 프로그래밍 패러다임을 따르고 있다.
함수형 언어는 수학의 함수를 프로그래밍 언어 설계에 적극적으로 반영한 것이다.
부작용(side-effect)이 없는 함수
함수의 실행이 외부에 영향을 끼치지 않는 함수
// 순수하지 않은 함수의 예
// 두 y는 서로 값이 다를 수 있다. (random() 함수가 호출 때마다 결과가 달라지므로)
y = random() * random();
z = random();
y = z * z;
이름이 없는 함수
함수를 다루는 함수
함수형 언어에서는 함수도 값으로 취급한다. 따라서 정수 1이나 인수를 제곱하는 함수나 동등한 입장에서 다룰 수 있으며, 함수의 결과 값으로 정수를 반환하듯이 함수를 반환할 수도 있다.
리액트는 함수형 프로그래밍 철학을 받아들여 만들어진 라이브러리로 함수형 프로그래밍의 대표 특징 중 하나인 '불변성'을 강조한다. 이에 더해 함수형 컴포넌트가 소개되면서 더욱 더 함수형 프로그래밍과 관련성이 높아졌다.
사이드 이펙트가 발생하지 않아 같은 입력에 대해 항상 같은 출력이 보장된다.
이 특징은 프로그램의 검증이 쉽고, 최적화를 가능하게 하며, 동시성 프로그램을 작성하기 쉽게하는 장점이 있다.
First-class 함수란 변수에 할당할 수 있고, 다른 함수의 인자로 전달할 수 있으며, 다른 함수의 결과 값으로 반환될 수 있는 함수이다.
함수를 하나의 값처럼 다룰 수 있기 때문에 객체지향 패러다임에서 클래스를 재사용하는 것처럼 함수를 재사용할 수 있고, 핵심 코드를 boiler plate 없이 간단하게 표현할 수 있다.
higher-order function(고차 함수)이란 인수로 전달된 함수를 이용하여 만든 새로운 함수를 의미한다.
개발자가 프로그램을 간결하게 작성할 수 있도록 도와준다.
지연 연산은 어떤 값이 실제로 쓰이기 전까지 그 값의 계산을 최대한 미룬다.
값을 미리 계산하여 저장하지 않기 때문에 공간을 절약할 수 있고, 값이 꼭 필요할 때만 계산하기 때문에 프로그램의 성능에도 긍정적인 영향을 준다. 지연 연산을 이용하여 무한수열, 피보나치수열도 표현할 수 있다.
지연 연산은 주로 메모이제이션과 함께 사용된다. 즉, 값이 필요할 때 계산을 수행한 후, 다음에 해당 값이 필요할 때는 계산하지 않고 캐싱해 둔 값을 재사용하는 것이다.
함수형 프로그래밍은 객체 단위로 문제를 분해하지 않고 함수들의 집합으로 문제를 분해하는 방법론으로, 객체지향 프로그래밍이 가진 문제점을 극복할 수 있는 장점을 지닌다.
객체지향 프로그래밍은 복잡하고 규모가 큰 소프트웨어도 개발 및 관리가 용이하다는 장점을 지닌다. 즉, 여러 객체를 조합하여 큰 문제를 해결하는 상향식 해결법이란 장점을 지닌다.
그러나 이런 객체지향 프로그래밍은 다음과 같은 문제점을 지니고 있다.
함수의 비일관성
동일한 입력에 대해 다른 결과를 반환하는 경우가 있다.
객체 간 의존성 증가
객체 간 상호작용을 위해 함수가 다른 객체의 함수를 호출한다. 따라서 함수가 외부 세계에 의존적으로 동작하기 때문에 재사용성이 떨어지고, 프로그램의 복잡도가 증가한다.
객체 내 상태 변화 제어의 어려움
객체 내 변수는 객체에서 제공하는 함수에 의해 변경된다. 대부분의 함수는 객체 내 변수들을 외부에서 변경 가능하도록 마련하는 공식적인 통로로서, 다수의 외부 경로를 통해 객체 내 함수가 호출되면 어느 시점에 어떤 외부경로를 통해 상태가 변경되었는지 추적이 어려워진다.
함수형 프로그래밍은 함수의 수행결과를 입력 값에만 의존하도록 설계하기 때문에 시스템의 불규칙한 상태 변화에 의한 예기치 못한 영향을 최소화할 수 있다. 즉, 버그나 외부의 시스템 공격과 같은 문제가 나타났을 때 빠르게 원인을 찾아 고치기에 용이하다. 이에 더하여 객체 내 상태변화가 없도록 설계했기 때문에 유지보수가 편리하다.