함수형 프로그래밍은 어떻게 할건지(How)를 나타내기보다 무엇(What)을 할 건지를 설명하는 방식입니다.
연봉이 떡상한다고? 함수형 프로그래밍! 10분만에 이해하기
함수형 프로그래밍은 코드 작성 스타일입니다. 함수형 프로그래밍을 배우면 원하는 언어에서 적용할 수 있으며, 문제를 해결할 때 새로운 관점과 접근 방식을 제공합니다. 함수형 프로그래밍은 정신적인 자세이며, 그것을 배우는 것은 좋은 개발자로 성장하는 데 도움이 됩니다. 함수형 프로그래밍은 깨끗하고 버그가 적은 코드를 작성하는 데 도움이 됩니다.
함수형 프로그래밍은 프로그래밍 패러다임 중 하나로, 계산을 수학적 함수의 계산으로 취급하고, 상태와 가변 데이터를 피하는 프로그래밍 방식입니다. 이러한 방식은 함수의 입력과 출력만으로 결과를 예측하고 추론할 수 있어서, 코드가 예측 가능하고 안정적이며, 디버깅 및 테스트가 쉽다는 장점이 있습니다.
함수형 프로그래밍에서 함수는 일급 객체로 취급되며, 함수를 값으로 취급할 수 있습니다. 이러한 특징으로 인해, 함수형 프로그래밍에서는 고차 함수, 클로저, 커링 등의 기술을 사용하여 코드를 더욱 간결하고 추상화된 수준으로 작성할 수 있습니다. 또한 함수형 프로그래밍에서는 불변성을 중요시합니다. 즉, 변수의 값을 변경할 수 없으며, 함수는 부수 효과를 일으키지 않아야 합니다. 이를 통해 코드가 안정적이고 예측 가능하며, 병렬 처리가 용이하다는 장점이 있습니다.
PureFunction
순수 함수는 입력값에 대한 결과값만 반환하기 때문에 부작용(Side Effect)이 없으며, 외부의 상태를 변경하지 않습니다. 따라서 순수 함수는 예측 가능하고 안정적입니다. 또한 순수 함수는 동일한 입력값에 대해서는 항상 동일한 출력값을 반환하므로, 테스트와 디버깅이 용이합니다.
순수 함수를 사용하면 코드의 복잡성을 줄이고, 코드의 재사용성을 높일 수 있습니다. 또한 순수 함수를 조합하여 새로운 함수를 만들 수 있기 때문에 코드를 간결하게 만들 수 있습니다.
함수형 프로그래밍에서 순수 함수(Pure Function)는 다음과 같은 특징을 가지고 있습니다.
- 함수의 입력값만으로 출력값을 계산합니다.
- 함수 외부의 상태를 변경하지 않습니다.
- 같은 입력값에 대해서는 항상 같은 출력값을 반환합니다.
Immutability
불변성(Immutability)이란, 객체의 상태가 변하지 않는 것을 의미합니다. 즉, 한 번 생성된 객체의 내부 상태는 변경되지 않으며, 새로운 객체를 생성하여 그 값을 갱신합니다. 불변성은 함수형 프로그래밍에서 매우 중요한 개념 중 하나입니다.
불변성을 유지하는 것은 여러 가지 이점이 있습니다. 먼저, 불변성을 유지하면 객체의 상태를 변경하는 부작용(Side Effect)이 발생하지 않기 때문에, 예측 가능하고 안정적인 코드를 작성할 수 있습니다. 또한, 멀티 스레딩 환경에서도 안전하게 사용할 수 있습니다.
불변성을 유지하면 객체가 불변하므로, 객체를 복사하는 데 드는 비용이 높아질 수 있습니다. 따라서 불변성을 유지하는 것이 항상 최적의 선택이 아닐 수도 있습니다. 불변성을 유지하지 않으면서도 안정적인 코드를 작성하기 위해서는, 객체의 변경을 허용하는 대신 새로운 객체를 생성하는 방법을 사용할 수 있습니다. 이를 통해, 객체를 갱신할 때마다 새로운 객체를 생성하여 변경하므로써, 객체의 상태가 변하지 않는 것처럼 보이게 할 수 있습니다.
C#에서도 불변성을 유지하는 방식으로 함수형 프로그래밍을 구현할 수 있습니다. 예를 들어, string 클래스는 불변 객체로 구현되어 있습니다. 따라서, 문자열을 수정하려면 항상 새로운 객체를 생성해야 합니다.
string str = "hello";
str.ToUpper(); // "HELLO"
Console.WriteLine(str); // "hello"
위 예제는 str 변수에 “hello” 문자열을 저장한 뒤, ToUpper() 메서드를 호출하여 대문자로 변환한 문자열을 반환합니다. 하지만 str 변수에는 여전히 “hello” 문자열이 저장되어 있습니다. 따라서, 이를 출력하면 “hello”가 출력됩니다. 이러한 방식으로 불변성을 유지함으로써 코드의 안정성과 예측 가능성을 높일 수 있습니다.
High Order Function
고차 함수(Higher-Order Function)란, 함수를 인자(argument)로 전달하거나, 함수를 반환값(return value)으로 사용하는 함수를 말합니다. 즉, 함수를 인자로 받거나, 함수를 반환하는 함수입니다.
고차 함수는 다른 함수를 인자로 받아 그 함수를 실행하거나, 다른 함수를 반환하는 등의 작업을 수행할 수 있습니다. 이러한 기능을 통해 함수형 프로그래밍에서 많은 유연성을 제공합니다. 고차 함수를 사용하면 코드의 중복을 제거하고, 코드의 재사용성을 높일 수 있습니다.
고차 함수를 사용하는 대표적인 예시로는, map, filter, reduce 등의 함수가 있습니다. 이러한 함수들은 함수를 인자로 받아 다양한 작업을 수행할 수 있습니다. 또한, 고차 함수는 클로저(Closure)를 사용하여 상태를 유지할 수 있습니다. 이를 통해, 함수의 실행 결과를 외부에서 수정할 수 없으므로, 안정적인 코드를 작성할 수 있습니다.
즉 고차 함수는 다른 함수를 인수로 받거나, 함수를 반환하는 함수입니다. 이를 통해 코드의 중복을 줄이고 재사용성을 높일 수 있습니다.
Func<int, int> add(int x) => y => x + y;
var add5 = add(5);
var result = add5(3); // 8
위 예제는 add라는 함수를 정의하는데, add 함수는 int 타입의 인수 x를 받아서 int를 반환하는 함수를 반환합니다. 이후, add(5)를 호출하여 5를 더해주는 함수를 반환하고, add5에 저장합니다. 이후, add5(3)을 호출하여 5와 3을 더한 8이 result 변수에 저장됩니다.
Lambda Expression
람다식(Lambda Expression)은 함수형 프로그래밍에서 사용하는 익명 함수를 표현하는 방법 중 하나입니다. 람다식은 이름이 없는 함수를 정의하고, 이를 변수에 할당하거나, 다른 함수의 인자로 전달할 수 있습니다.
람다식은 함수 인자 -> 함수 본문 형태로 작성됩니다. 이를 통해, 함수를 정의하는 것과 유사한 방법으로 익명 함수를 작성할 수 있습니다. 람다식을 사용하면 코드의 길이를 줄이고, 가독성을 높일 수 있습니다. 또한, 함수형 프로그래밍에서 많이 사용되는 고차 함수와 함께 사용하면 더욱 강력한 기능을 제공합니다.