Functional programming in C++
medium.com
medium.com
#include <climits>
int count_common_chars(const std::string& str) {
int n = 0, common = 0, counts[CHAR_MAX - CHAR_MIN + 1] = {};
for (char c : str) {
if (c == '\n') {
common = 0;
n++;
}
if (counts[c - CHAR_MIN] == n) {
counts[c - CHAR_MIN]++;
common++;
}
}
return common;
}
Tastes may vary, but to my eyes the imperative version has some advantages:* Faster
* No allocations
* No dependencies
* Easy to add an early return if common == 0 (in the functional version it's much harder)
Shouldn't that be counts[CHAR_MAX - CHAR_MIN + 1] ?
In your code \n must be a line separator rather than a line terminator. (Otherwise, if the last line is \n terminated, the function returns 0.)
1) C++ already provides a transform and accumulate (just for starters) which are much like map and fold. Isn't it better to learn to use the built-in tools rather than rely on a library? There is quite a lot of functional-style stuff in the standard already.
2) The cost of these abstractions is not clear. You can do a lot of functional idioms in C++, but often a tremendous amount of copying is happening compared to an imperative solution, because C++ lacks functional data structures under the hood.
3) Points 1) and 2) above are largely addressed by proposals for C++20 specification, such as the Range library.
As for cost, I had a C++ teacher who once sat on the standards committee. His advice: Always use the algorithms library even if it "feels" like it is costlier. Reasons:
1. Much lower likelihood of having a bug.
2. Virtually every time someone decided writing an explicit solution rather than using the algorithms library, it did not perform better (even in cases where it seems "obvious" it should).
Are you sure about that? The standard does not guarantee which order transform will actually run and apply the function, but that is a different matter than the order of the final result. I'm pretty sure the standard guarantees that. If you have side effects and require application order guarantees, for_each is the one to use.
edit: this SO answer from a Google engineer suggests I am correct: http://stackoverflow.com/questions/34167638/stdtransform-ord...
I think this piece would have been much more compelling if it didn't end with this line.
I personally would never want to maintain that code (in C++). I mean hey, look, I get it. Functional programming is awesome. But with all of the magic behind the scenes needed to make that work in C++, it just feels like an overly complicated, Rube Goldberg-esque solution to a relatively simple problem.
https://github.com/BartoszMilewski/Okasaki
https://github.com/fons/functional-cpp
There is a lot of interest in making this happen in C++, which is awesome.
https://www.cics.umass.edu/~yannis/fc++/fc++-sigplan.pdf
Note that this the library is now obsolete, but it did introduce a lot of techniques.
For an established C++ or Python programmer, being able to "make one language do everything" is great and functional programming style is "the right tool" for some specific needs. Preferring certain "pure" languages for the purpose of doing functional programming, regardless of the domain, can be an interesting experiment but is completely backwards from a practical engineering point of view.
Well, it's a demonstration that C++ can be made into an adequate tool. The right tool? That might be a bit of an overstatement...
As you can probably tell, languages that support one paradigm aren't particularly successful. This is painfully clear in the case of F#.
But it's part of a larger project. That project could have other constraints that make C++ a better choice (or it could be an existing codebase).
Sure, it can be done, but it would go against the grain of the language (imho).
That said, this makes me a bit nervous about shoe-horning functional programming into contexts where it is inappropriate. FunctionalPlus aside, C++ is very clearly designed for an object oriented style (even the name, C++, refers to "C plus objects").
Going too far down the path of working against the intent of the standards committee seems like a recipe for trouble (unless you're just talking about hobby projects).
The example code in the article also makes use of objects such as std::string, sets etc.
I actually happen to like iostream, for the reasons of it being standard and extendible; just don't expect any particular performance out of it.
That said, I don't disagree that C++ can support functional programming. I would just argue there are languages better suited for this.
(edited for clarity)
The STL is mainly a generic library, not an OO library.
https://github.com/kennytm/utils/blob/master/traits.hpp#L47-...
Wow that scares the heck out of me to do that!
CPP macros only start to get weird once you start implementing control structures in them. http://pastebin.com/raw/tNaX99eA (Yes, that's code from a project I work on. Don't ask.)
As far as macro's go, that is not so bad and generating the exact same code over and over is asking for errors too. Not sure of how else to do something like that, but I could be ignorant.