C++ is usually synonymous with object-oriented programming (OOP), and further replenished in no small measure by popular technical literature. This article tries something different – functional programming with C++ using the open source FC++ library from Yannis Smaragdakis and Brian McNamara. Learn how you can use FC++ to implement basic functional programming.
Functional C++ would be nice, since it barely works as it is.
It works fine as it is, otherwise it wouldn’t be used in a vast amount of applications out there.
C++ also supports functional constructs in STL, for example many recursive functions from functional programming are supported (equivalents of map/fold/filter). STL also supports some currying (bind*).
A functional library for C++ that adds more construct is a nice addition, but it won’t bring many other important virtues of functional programming such as pattern matching and algabraic data types.
It’s used in “vast amounts” because the ideas are good, not because the implementation is.
Yes, but “barely works” accurately describes its usefulness. Just off the top of my head:
1. There are functions missing. copy_if, anyone? Or versions of the algorithm functions that work on collections? Of course, all this can be implemented relatively easily… but why should the user do it?
2. Yes, there is bind. bind1st, bind2nd… why no bindnth?
3. Using these functions for anything but the most basic task requires more boilerplate code (classes with constructors & such) than the lines of code that could be spared by them, because C++ does not support anonymous classes, let alone anonymous functions.
4. And if you fail to get the code right on the first time? Good luck with the error messages then…
I am sure there is a lot more. Each time I use <functional> and <algorithm>, I just become frustrated. I understand that C++ is not Ruby nor Lisp, but I am sure they could have done better than that.
Edited 2010-08-18 06:30 UTC
It’s an oversight, but included in the C++0x draft.
I am not sure what point you make here, since they work on iterators over collections.
See bind in TR1.
General point taken, although C++0x supports lambda functions. Besides that, one can usually write a struct implementing operator(), so in most situations the default constructors are fine.
After spending some time with C++ it becomes easier to read some error messages. And it’s not as if Haskell type-related error messages are easy to read (and this is coming from someone who likes Haskell).
As someone who has done paid C++ programming for years, I have to say it is not all that bad. There is some overhead, because it is a statically-typed language, but once you know it, it ain’t so bad, and gives a lot of opportunity for optimization. It’s an old language, and if you want to see it redone properly, look at D. Besides that, it’s not as if Ruby procs and blocks are elegant in any way.
I’d like to add that the error messages he speaks about are probably the GNU compiler’s problem, not C++ itself. Have a look at llvm (I’m not sure about the names here), the error mesages are awesome.
LLVM has great error messages – unfortunately that’s all you are going to get if you try to compile a valid C++ program.
“Eben Moglen on LLVM: “Nobody has ever tried before, to build a multi-platform C compiler solely in order to undermine freedom” (groklaw.net)
http://www.reddit.com/r/programming/comments/cyt6k/eben_moglen_on_l…
LLVM actually compiles many programs these days. It’s even self-hosting last I checked.
As far as the comments about it being anti-free….I’d more say the GCC’s view is worse. LLVM exists because GCC is so horribly coded that it’s impossible to try to modify it. OSS has many tools for its defense, intentional code obfuscation should not be one of them.
Being self hosting is much easier than compiling the real world C++ code out there; you can achieve this by a conservative coding style, for example.
GCC is improving; they even allow C++ these days (about time, it’s 2010).
Sure cite a lot of smack talk. Go build the damn thing yourself and find out.
I thank the heavens for that, every day
Hint: I gets a lot more fun with boost::bind (already available). Much more flexible and easier to read than the bind1st and bind2nd etc. stuff. Also works nice with member functions.
Then there are lambda expressions in the new standard (while boost::lambda already exists). The syntax is hideous, but that’s the fate of FP-ish programming in C++ it seems :/
COBOL and Fortran and PHP are used by a lot of applications. Windows is used by most desktop users. So I think the argument from popularity that you employed probably isn’t in your favor.
It proves my point: it works as it is.
Having some functional constructs in C++ would be nice but since the language and its libraries are not functionally oriented the usefulness of this approach is limited anyway. It’s like writing an OO oriented code in C – possible but with many obstacles and not very rewarding.
A question: how to write a functional program in a language without a garbage collector? Is there any functional language not using one?
Actually, STL is probably as functional as you can get in a classical imperative language. It popularized functional constructs in statically typed languages before the recent surge of Haskell, OCaml, Scala, and others.
MLKit implements ML without garbage collection.
Really, if you want to attack functional programming in C++, there are far easier shots: such as the lack of algabraic datatypes and pattern matching.
(I agree with you regarding C++)
Thanks, I’m reading about it now. I wonder what are the limitations of this “region based memory management”.
Lisp programmers are doing fine without these features (although Lips probably has some form of pattern matching) so these constructs don’t define functional programming as such. But a functional language without a GC – that’s interesting.
I guess there is not one single definition of ‘functional programming’, though everyone seems to agree on some things that a functional language requires:
– lambdas/anonymous functions
– cheap recursion (tail recursion elimination)
At least Scheme provides those, AFAIK Common Lisp does not require tail recursion optimization. That said, I can not understand all the enthusiasm for Lisp, especially not the ‘almost an esoteric experience’ crowd. Sure, it is nice that it is written in S-expressions that can be processed with Lisp again. Which is by the way not so special, Prolog, which is also an old language can also be decomposed in Prolog. But it lacks a lot that ML and Haskell offer. Sometimes it’s not bad to sacrifice some simplicity for more syntax .
Essentially it all boils down to having functions as first class elements, so you can use them as any other data type.
Pure functional programming adds one more requirement – everything (at least in the “pure” section of the program) is immutable, so that you can look at the whole program and process it (e.g. expand/simplify) as a single static algebraic expression.
Rest is just implementation details (tail recursion) or convenience constructs (pattern matching). Being static or dynamic division is orthogonal to being functional (just like it is to being orthogonal to OO). Same is true in respect to being strict or lazy.
Lisp is a dynamic language so many of Haskell or ML features simply don’t apply there. It doesn’t mean you couldn’t implement them in lisp – its syntax is very rich, it just happens to be encoded as list of lists and symbols instead of lines of characters.
The whole fuss about lisp syntax is related to macros. It’s the only lisp feature that hasn’t yet been rediscovered in more mainstream programming languages. What they do is looking at the piece of the code as a tree, analyzing it and transforming it (at compile time) to produce another piece of code. This gives the programmer to add new special forms to the language almost as easily as you can add a function. In fact many of “built in” lisp features are implemented this way instead of being hardcoded in the compiler.