Functional Programming
함수형 프로그래밍을 한 줄로 요약하자면 pure function을 first class object로 보는 것이다. 이를 통해 데이터와 로직을 분리한다. pure function이란 함수 밖에 영역에 영향을 끼치지 않으며, input이 같으면 언제나 output이 같은 함수를 뜻 한다. 이를 first class object로 본다는 것은 함수를 parameter처럼 주고받을 수 있게 만들었단 뜻이다. 즉, 고차함수(Higher order function)를 만들거나 콜백(callback)을 구현할 수 있다.
함수형 로직으로 프로그래밍을 설계하면 쉽게 병렬 프로그램을 짤 수 있다. 요즘 나온 언어(rust, clojure)는 함수형 프로그래밍을 염두해 두고 만들었다. 그러나 C++에서도 함수형 프로그래밍을 할 수 있다.
아래는 함수형 프로그래밍을 할 때 사용하는 대표적인 두가지 방법에 대해서 서술한다.
CSP (Communicating Sequenctial Process)
CSP는 동시성 프로그래밍에서 thread간에thread 간에 소통할 때 message queue를 사용하는 방식이다. thread 간에 공유되는 메모리를 사용하지 않고 message queue를 활용해서 처리하는 방식이다. Erlang, MPI 언어들이 이런 방식을 사용했다. 대표적인 설계 패턴으론 Actor Model이 있다. 아래의 State Machine을 하나의 Thread에서 관리하고 State에 대한 이동을 Message Queue에서 사용하는 패턴이다. (java의 Akka framework가 Actor model이라고 한다.

State Diagram을 그렸을 때, 각각의 State(Node)가 맴버 함수로 나타난다. 여기서 handle은 lambda 객체를 return 하고 받는 메시지 타입이다. 다른
struct card_inserted {
std::string account;
};
class atm {
messaging::receiver incoming;
messaging::sender bank;
messaging::sender interface_hardware;
void (atm::*state)();
std::string account;
std::string pin;
void waiting_for_card() {
interface_hardware.send(display_enter_card());
incoming.wait();
}
void getting_pin();
public:
void run() {
bank.handle<card_inserted>(
[&](card_inserted const& msg) {
account = msg.account;
pin = "";
interface_hardware.send(display_enter_pin());
state = &atm::getting_pin;
state = &atm::waiting_for_card;
try {
for (;;) { // while(true), busy waiting
(this->*state)();
}
} catch (messaging::close_queue const&) {
}
}
);
}
};
Continuation Style Passing, in C++
위에서 언급했듯, first class object는 then을 이용해서 function call back을 깔끔하게 구현할 수 있다.
만약 then이 없다면 async로 callback할 때마다 들여 쓰기가 써져서 callback 지옥이 된다. 이때 then을 쓰면 깔끔하게 코드를 쓸 수 있다.
doSomething(function(result1) {
doSomethingElse(result1, function(result2) {
doAnotherThing(result2, function(result3) {
doFinalThing(result3, function(result4) {
console.log(result4);
});
});
});
});
fetchData()
.then(data => processData(data))
.then(data => saveData(data))
.then(result => console.log(result))
.catch(error => console.error("Error:", error));
단, C++20에서는 then을 쓸 수 없다. then은 cuncurrency TS에 있다. C++20부터는 latch barrier 같은 몇몇 기능만 concurrency TS에서 넘어왔다. (아래 stackoverflow 링크 참조)
ref.
'Engineering > C++' 카테고리의 다른 글
Chapter 4. Synchronizing Concurrent Operations. (2) - future (0) | 2025.01.22 |
---|---|
Chapter3. Sharing Data Between Threads (1) | 2025.01.20 |
Chapter 4. Synchronizing Concurrent Operations (0) | 2025.01.18 |
C++ STL 정리 (2) | 2024.12.19 |
C++17 Class Template Argument Deduction (CTAD) (0) | 2024.12.19 |