DEV Community

Discussion on: Functional programming in C++, Python, etc.

 
nahiyan profile image
Nahiyan Alamgir • Edited

I figured out that you can't have a 100% "pure functional" program in languages which aren't built for that, due to lack of features I've mentioned in this post.

However, the main concept is not to have 100% pure functional program but to have a pure functional core and an imperative shell. Google "functional core, imperative shell" for details. The idea is to push the imperative code far off to the edge and keep the core pure functional.

And based on that, I've written a demo Hello World program in C++. The idea is that you build a pure functional core which returns actions (just like you do in Haskell) - same input yields same output with no side effect, while you have an imperative shell which executes the actions. Here's my code:

gist.github.com/nahiyan/4ea3181b6b...

Thread Thread
 
rhymes profile image
rhymes • Edited

What's the advantage here? I mean over the imperative way of outputting strings over stdio.

You're basically storing in memory potentially huge amount of strings and having to call execute instead of just using cout 🤔 The example is also encapsulating IO in a class, I'm not sure which part is functional 😬

Why is this better than creating a buffer and then printing it out when needed?

Thread Thread
 
nahiyan profile image
Nahiyan Alamgir

I didn't write an efficient IO monad, I just wanted it to work somehow. Even if I wrote an efficient IO monad, there is no doubt that imperative programming is likely to be more memory efficient. If you're aiming for memory efficiency, go for it. But in the modern age of cheap and fast computing, we don't really care about the efficiency if we get benefits which are worth it.

The benefit here is that the functions aren't dealing with side effects, they are only declaring side effects, keeping them pure. Declared side effects are executed by the imperative shell. Pure functions are just like the ones you see in mathematics, they lead to much less bugs, are easier to test, debug, etc. Imagine writing a unit test for pure functions vs a non-pure function (nightmare to say the least). This is pretty much how Haskell or any declarative pure functional programming language works.

The function I wrote "main_" only returns a declared side effect (IO instance), is a pure function and is super easy to test, I don't even have to mock anything here. That's the functional part of the program. The rest is the imperative shell.

P.S. I'm not storing huge amounts of data in the memory here. If I ever need to output huge text, I'd deal with them in chunks. You can argue about the same thing when using recursion in functional programming rather than a loop (which can also lead to max call stack overflow errors in some languages). Recursion uses much more memory than a simple for/while loop. But when we're doing functional programming, we're considering the benefits of having more maintainable code.