

Functional Programming in C++ (2013) - ScottWRobinson
https://web.archive.org/web/20130819160454/http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/

======
vezzy-fnord
This is from 2013, and the original title is "Functional Programming in C++".
Moreover, Carmack never makes a statement that functional programming is the
future anywhere in this article. The closest he says is "Formal systems and
automated reasoning about software will be increasingly important in the
future," which is a markedly different sentiment.

That said, the problem of not understanding possible code states does not seem
to be purely a result of the internal software structure, but how it interacts
with outside components, including the OS (if any).

There is a combinatorial explosion of the state space as a program's
dependencies increase. As such, the most practical way to deal with this is
crash-only software whereby components do not perform complicated error
recovery, but are simply fenced and restarted to known good states with
persistence used to ensure that the component can return to its prior point of
operation quickly.

FP is useful for writing software like this, but not necessarily pure FP or
even a single paradigm.

~~~
dang
Thanks re the title. Submitters: the HN guidelines explicitly ask you not to
rewrite titles like this, unless they are misleading or linkbait.

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

(Submitted title was 'John Carmack: Why functional programming is the
future'.)

~~~
currysausage
[https://news.ycombinator.com/submit](https://news.ycombinator.com/submit)
should have a link to
[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html).
(Edit:) I know there is a link in the footer of every other page, but when you
open the submit form in great excitement, it's easy to forget about that (as
demonstrated by this submission).

------
astazangasta
I just can't get behind all of this. Sure, its great to be able to reason
clearly because you can see your whole state, but its exhausting always
carrying your context around like a hobo with a huge backpack full of junk. Am
I mistaken?

~~~
saryant
Exhausting is being in this situation:

    
    
      object Foo {
    
        var x: Int = 0
    
        def bar(y: Int) = x + y
    
      }
    

And trying to figure out what bar will return at any given point.

~~~
pekk
Are you somehow not in control of how x is being changed? You seem to have
said that literally any statefulness is "exhausting".

~~~
S4M
What convinced me that avoiding mutations as much as possible was having to
deal with code like that (in java):

    
    
        public class MyBigClass() {
            private int a;
            private int b;
    
            //hundreds of lines of code
    
            private int calculateSomething() {
                //do something
                a = a+1;
                return b*b;
            }
    
            //hundreds lines of code
    
            private int calculateSomethingElse() {
                int c = calculateSomething();
                return a+c;
            }
    
            //hundreds of lines of code
            public returnSomething() {
                return calculateSomethingElse();
            } 
        }
    

In this example. It's hard because you have to remember constantly which
functions are changing your classes before you use them, and if you haven't
written the functions, it's very easy to introduce a bug by involuntarily
modify the states using the function _calculateSomething_ , just wanting its
output and not the modification of _a_.

~~~
pekk
That demonstrates some design flaws of Java, yeah, because your "private"
variables are effectively just globals anyway.

The guy who is not using encapsulation at all this year will be making similar
mistakes (massively long bodies, proliferation of unnecessary entities, etc.)
if he switches to functional programming next year. It's not a panacea.

I'm afraid this doesn't demonstrate that any tiny bit of statefulness is
"exhausting."

------
overpaidgoogler
One difficulty with functional style c++ is just how verbose it is. Every time
I tried to use std::transform (the equivalent of "map") I had to delete it and
rewrite as a loop because it was just too hard to read. Functional style on a
large scale is still possible.

~~~
femngi
It really irks me that the std algorithms library seems to have been designed
without any consideration for usability given how much I would love to rely
heavily on the generic algorithms it contains. For example consider the simple
task of testing to see if an element exists in a container:

    
    
        if (std::find(container.begin(), container.end(), element) != container.end())
    

My fingers are now cramping and my eyes are crossing trying to read that. It
beggars belief that overloads don't exist which take an entire range which is
all I want to do 99% of the time.

~~~
nly
Well the containers that have fast lookup (set, map and their unordered_ and
multi_ counterparts), all have efficient .find() member functions. The general
philosophy of the idealised STL is not to provide you with anything you can
compose efficiently yourself.

A 3-4 line template will will give you a terse boolean contains() method, but
it won't give you any big-O guarantees, and having such a thing would
encourage very inefficient patterns (like calling contains() and then doing a
find() if it's true, which effectively does the lookup twice). Why introduce a
weak abstraction? If you're forced to write it yourself you're more likely to
understand the implications.

Alex Stepanov, who wrote the original STL, is very much a believer in
fundamental indivisible building blocks like iterators and algorithms and
careful API design. To grok more about why things are the way they are, I
recommend watching his "Efficient Programming with Components" lectures[0].
Over the course he builds up, in excruciating detail, an implementation of
merge sort, reasoning about, and discussing with his students, the
implications of almost every line of code.

And yes, Stepanov complains about the lack of terseness and expressiveness in
C++ as well.

[0]
[https://www.youtube.com/playlist?list=PLHxtyCq_WDLXryyw91lah...](https://www.youtube.com/playlist?list=PLHxtyCq_WDLXryyw91lahwdtpZsmo4BGD)

~~~
pcwalton
There _is_ a legitimate complaint with that specific example, though: having
to write .begin() and .end() is obnoxious instead of using more modern
iterators/ranges.

~~~
nly
well the slightly more concise way of writing it is this:

    
    
        auto e = end(container);
        if (e == std::find(begin(container), e, element)) { ... }
    

...but yeah, it sucks. If I were doing this though, i'd to be encapsulating
things in to a higher level abstraction. Seeing std::find in more than 1 place
in a file is a red light for me.

------
vivekian2
On an unrelated note, sad to see altdevblogaday has gone away :( Sure the
pages are cached somewhere, but the posts always made for interesting reading.

~~~
rootlocus
Couldn't agree more. It went away shortly after I discovered it, and although
there's a lot of awesome information in the archives, it's a shame no new
content is being added.

------
brador
I've noticed hackers/self taught prefer functional programming styles and CS
degree holders prefer the more common style.

~~~
varelse
I'm self-taught and while I can see the formal appeal of functional
programming, I'm a low-level coder that implicitly reduces state to bare-metal
registers and cache in GPUs and embedded systems. Since I'm already sweating
bits over state down to the byte-level, I just don't see what FP would improve
on this.

~~~
peterfirefly
The big improvements often come from better algorithms and data structures.

Using a function style or a higher-level language sometimes makes it easier to
modify the program (and hence use a better algorithm).

I remember people swearing by assembly language back in the 80's, thinking C
would make their programs slow and bloated. In reality, it was usually the
other way around because C code is much more malleable than assembly. You
might want to give FP a second look.

~~~
varelse
There is a very active attempt to make GPUs FP-friendly called C++AMP. And for
streaming transformation tasks, it's a nice abstraction.

[https://en.wikipedia.org/wiki/C%2B%2B_AMP](https://en.wikipedia.org/wiki/C%2B%2B_AMP)

However, my best algorithms are stylistically equivalent to a map-reduce with
combiners entirely in GPU-space. The map tasks themselves carry all the scope
I need. They are independent units of work executed by independent warps
(synchronized groups of 32 GPU threads) whose results need to be reduced to
floating point numbers. That reduction is done with 64-bit fixed point atomic
ops (my combiners) because:

1) This insures the sum is deterministic

2) Ever since Kepler (GK104), it's much faster than reduction buffers and uses
a fraction of the memory

3) It's possible because I can precompute the expected dynamic range and
adjust the fixed point exponent accordingly

Now given that, do you see a functional programming equivalent that
significantly improves on this design? I haven't yet.

~~~
peterfirefly
map-reduce is already functional, isn't it?

Who cares if you implement the combining with atomic ops or by sending data to
a process that does the combining or whether you stuff the data in a buffer
and then reduce it afterwards?

(Of course you might care for performance reasons -- but conceptually it's the
same thing.)

~~~
varelse
Yes, it is true conceptually, but:

1) "Who cares" is not the sort of thing you want to say to someone who cares
about performance because:

2) Sending the data to buffers for subsequent reduction was the first
implementation (2009). But it was a memory hog and a 5% or so slowdown to
perform the reduction subsequently rather than concurrently with Atomic Ops
and 64-bit Fixed Point (2012).

But I guess what we're arriving at is that this is essentially a functional
design using imperative code? I can live with that.

~~~
peterfirefly
> But I guess what we're arriving at is that this is essentially a functional
> design using imperative code? I can live with that.

Yep. That's precisely what it is.

