
Functional programming in C++ - ingve
https://medium.com/@nirjhor/functional-programming-in-c-8bdbd903ee32
======
cousin_it
Quick and dirty imperative version:

    
    
        #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)

~~~
tzs
> counts[CHAR_MAX - CHAR_MIN]

Shouldn't that be counts[CHAR_MAX - CHAR_MIN + 1] ?

~~~
cousin_it
Good catch, thanks!

------
hellofunk
Cool, but I'm left with some observations:

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.

~~~
BeetleB
transform in C++ is not that great. The standard does _not_ guarantee order is
preserved, which makes it virtually useless. People recommend for_each if you
want to preserve the order, but it's almost the same as writing a for loop.

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).

~~~
hellofunk
> The standard does not guarantee order is preserved

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...](http://stackoverflow.com/questions/34167638/stdtransform-order-
guarantees)

~~~
BeetleB
Ah, yes, you are correct. Will now happily use transform :-)

------
king_magic
"This is code I personally would love to maintain compared to what an
imperative version could look like."

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.

------
hellofunk
For the curious, there are many other stabs at doing functional programming in
C++:

[https://github.com/beark/ftl](https://github.com/beark/ftl)

[https://github.com/BartoszMilewski/Okasaki](https://github.com/BartoszMilewski/Okasaki)

[https://github.com/fons/functional-cpp](https://github.com/fons/functional-
cpp)

[https://cat.github.io/](https://cat.github.io/)

There is a lot of interest in making this happen in C++, which is awesome.

~~~
gpderetta
All great links, I just wanted to add a link to the library that started it
all, FC++:

[https://www.cics.umass.edu/~yannis/fc++/fc++-sigplan.pdf](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.

------
goatlover
I don't understand. What's the point? If you really want to do function
programming, use a language made for it, like Haskell or OCaml. Why the need
to make one language do everything. Whatever happened to using the right tool?

~~~
HelloNurse
This is a direct demonstration that C++ is the right tool. Most good modern
programming languages have sufficiently convenient syntax (in C++, function
types, templates and lambdas/closures) and sufficiently advanced libraries
(like the set implementation the article relies on) to allow a functional
programming style, which mostly means, like in the linked article, read-only
data structures and higher order functions.

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.

~~~
AnimalMuppet
> This is a direct demonstration that C++ is the right tool.

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...

------
plinkplonk
This makes as much sense as "Imperative Programming in Haskell".

Sure, it can be done, but it would go against the grain of the language
(imho).

------
nepstein
Nice article and effective demonstration of the FunctionalPlus library.

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).

~~~
nmeofthestate
I completely disagree - C++ is a multi-paradigm language and the C++ standard
is already chock full of non-OO stuff.

The example code in the article also makes use of objects such as std::string,
sets etc.

~~~
nepstein
I'm not sure I agree that STL that containers are explicitly not OO.

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)

~~~
hellofunk
The author of the first STL has famously said that, even after all these
decades, he has never written any C++ code that uses OO inheritance, because
he hasn't found a use for it.

The STL is mainly a generic library, not an OO library.

~~~
gpderetta
Yes, Stepanov is not exactly an OO fan. This interview with him, were he
declared that "OO is an Hoax", is great:

[http://www.stlport.org/resources/StepanovUSA.html](http://www.stlport.org/resources/StepanovUSA.html)

------
anthay
The Medium article has been removed. I think the same article (possibly under
a different author's name?) appeared here
[https://github.com/Dobiasd/articles/blob/master/functional_p...](https://github.com/Dobiasd/articles/blob/master/functional_programming_in_cpp_with_the_functionalplus_library_today_hackerrank_challange_gemstones.md)

------
hellofunk
take a look at one of the macros this library depends on:

[https://github.com/kennytm/utils/blob/master/traits.hpp#L47-...](https://github.com/kennytm/utils/blob/master/traits.hpp#L47-L53)

Wow that scares the heck out of me to do that!

~~~
PeCaN
What? That macro is super straightforward. Yes, generating C++ templates from
CPP macros is a little ugly, but it's not particularly hard to understand.

CPP macros only start to get weird once you start implementing control
structures in them.
[http://pastebin.com/raw/tNaX99eA](http://pastebin.com/raw/tNaX99eA) (Yes,
that's code from a project I work on. Don't ask.)

~~~
hellofunk
I didn't say it was hard to understand; but it does scare me to depend on any
C-style macro like that in a C++ project.

------
popcorncolonel
Why?

~~~
wmu
Years ago I saw a WWW server written in PostScript. People were also asking
"why?" :)

