반응형
함수형 프로그래밍?
함수형 프로그래밍 도입
- C++은 Object Oriented Programming(OOP) 패러다임이 중심이 언어이며, High performance가 필요한 곳에서 사용하고 있습니다. 그리고 이렇게 High performance가 필요할 경우 늘 cache hit을 쳐줘야 합니다.
- 이를 위해서는 Data oriented programming 스타일이 자연스럽게 C++스타일에 들어오게 됩니다.
- 이후 C++11부터 함수형 프로그래밍을 지원하기 위해 lambda expression을 도입.
그래서 간단히 함수형 프로그래밍이란?
- 함수를 object/variable 처럼 다루는 개념.
- 이를 활용하면? 다양하게 응용할 수 있습니다.
First-Class Object
C++0x에서는 람다 함수(Lambda Function)를 First-Class Object로 제공함으로써 코드 조각을 일반 변수처럼 사용할 수 있게 해줍니다.
- 변수와 자료구조에 저장하고 사용할 수 있다.
- 함수의 입력 값으로 사용할 수 있다.
- 함수의 반환 값으로 사용할 수 있다.
- 실행 시간에 생성할 수 있다.
Higher Order Function(HOF): 고차함수
- 하나 이상의 함수를 인자로 받습니다.
- 함수를 결과로 반환합니다.
- 위 둘 중 하나를 만족하는 경우를 HOF라 합니다.
Closure Function
- 함수로 함수를 반환하는 경우? 자바스크립트에서 주로 사용됩니다.
- 이는 함수를 호출한 상위 코드 블록의 변수들이 호출된 함수와 묶인 것을 뜻합니다.
function plus (a) {
let localVar = a;
return function (x) {
return localVar + x;
}
}
let plus3 = plus(3);
plus3(10)
// 출력: 13
#include <iostream>
class Plus {
public:
explicit Plus(int a): localVar{a}{}
int operator()(int a) const {
return localVar + x;
}
private:
int localVar;
};
int main(){
Plus plus3{3}
Plus plus5{5}
std::cout << plus3(10) << "\n";
std::cout << plus5(10) << "\n";
}
+ Callback Function
- 다른 함수에게 argument로 넘겨줄 수 있습니다.
- 함수의 결과값으로 인해 주로 비동기 처리할때 사용하며,
- 추가로, 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라고 하며 매개변수를 통해 콜백 함수를 전달받는 함수를 고차함수 라고 한다
lambda expression
Common lambda expression
[captures](params){ body }
auto lambdaPlus3 = [localVar = 3](int x){ return localVar + x; }
capture []
- capture by value: 함수 객체의 멤버 변수와 같은 역할 (deep copy)
- auto lambda = [localVar](int x) { return x + localVar}
- auto lambda = [=](int x) { return x + localVar}
- 위 두 식은 동일한 내용이며, [=]의 경우 람다 내부의 변수를 외부에서 capture by value로 받아와 넣어줍니다.
- capture by reference: 함수 객체의 참조 멤버 변수와 같은 역할 (shallow copy)
- auto lambda = [&localVar](int x) { return x + localVar}
- auto lambda = [&](int x) { return x + localVar}
- 위 두 식은 동일한 내용이며, [&]의 경우 람다 내부의 변수를 외부에서 capture by reference로 받아와 넣어줍니다.
- capture by this
- auto lambda = [this](int x) { return x + this->localVar}
- 멤버 함수 및 멤버 변수에 대한 액세스를 제공하기 위해 포인터를 명시적 또는 암시적으로 캡처합니다.
- auto lambda = [this](int x) { return x + this->localVar}
- 추가로 capture([])에 값을 넣어주지 않을 경우, 함수 외부에서 변수를 받아오지 않습니다.
- auto lambda = [](int x) { return x + localVar}
lambda function의 활용
- 지연 호출(Deferred Call)에 활용
- vector와 같은 자료구조에 저장한 후에 필요한 특정 시점에 호출하는데 사용합니다.
- 비동기 호출과 결과 코드의 응집성을 높이는 데 활용
- 비동기 처리 코드의 문제점은 비동기 요청 함수를 호출하는 곳과 결과를 처리하는 함수가 동떨어져 있어 로직 흐름을 파악하기 어렵다는 것입니다.
- 비동기 요청 함수를 호출할 때 결과 처리에 대한 코드를 람다 함수로 구현해 파라미터로 전달하면 코드 응집성이 높아질 수 있습니다.
- 일회성 함수를 쉽게 구현하기 위해 활용
- 특히 STL을 이용하는 데 유용합니다.
- *STL 알고리즘 함수들의 입력 파라미터로 람다 함수를 넘겨주면 따로 함수 객체를 정의하는 번거로움이 사라지고 코드 응집성이 높아지므로 STL 함수의 작동을 더 쉽게 이해할 수 있습니다.
- STL 알고리즘: #include <algorithms>
- STL 알고리즘 함수: for_each, sort...
- 템플릿을 대체하는 데 활용
- 람다 함수의 캡처 기능을 사용하면 람다 함수 몸체에서 외부 변수들을 마음껏 사용할 수 있을 뿐만 아니라 클로저(Closure)가 되어 함께 묶입니다.
- 이 기능을 활용하면 기존에 파라미터 타입과 개수 처리를 일반화하기 위해 사용하던 템플릿 사용을 지양할 수 있습니다.
- 템플릿 클레스를 사용하면?
- 함수의 파라미터가 늘어날 때마다 템플릿 클래스를 추가해 줘야하고,
- 코드가 직관적이지 않다는 점입니다.
- 템플릿 클레스를 사용하면?
참고
- [코드없는 프로그래밍] 함수형 프로그래밍: https://www.youtube.com/watch?v=eqepcz8tIak&list=PLDV-cCQnUlIa9cy9one-i9foU8DwErnSp&index=2
- [microsoft] Lambda Expression in C++ (en): https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-170
- [microsoft] Lambda Expression in C++ (ko): https://docs.microsoft.com/ko-kr/cpp/cpp/lambda-expressions-in-cpp?view=msvc-170
- [다음 블로그] 람다(lambda) 이야기: https://blog.daum.net/creazier/15309703
반응형
'Study: Software(SW) > SW: Language' 카테고리의 다른 글
[C++] 객체지향 프로그래밍: 변수 및 구조체 접근법 정리 (feat. struct vs class) (0) | 2022.07.23 |
---|---|
[C++] Modern C++ Programming Cookbook 정리 (0) | 2022.07.12 |
[C++] 조건부 컴파일 매크로(전처리기 지시어): Header Guard (#if, #ifdef, #elif, #else, #endif...) (0) | 2022.07.04 |
[C++] 병행 컴퓨팅: 순차, 병렬, 병행의 차이 (0) | 2022.07.01 |
[C++] 객체지향 프로그래밍: special member function (feat. L-value, R-value, std::move) (0) | 2022.06.30 |