Thread: Why is functional programming not more popular in C++?

  1. #1
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665

    Why is functional programming not more popular in C++?

    So, working in a heavily JS-based environment, I've grown accustomed to functional-based approaches.

    My question is, why aren't functional patterns more popular in C++? I'm reading the wiki page on monads right now because I'm determined to implement the Maybe monad just for fun this weekend and I'm just thinking, why isn't this done more?

    I think C++ is probably the best candidate to realistically carry functional programming right now. It's type system and C++11 features makes it realistic to implement and the advantage with C++ is that it allows you to eschew the functional paradigm when the OO or imperative ones would do well.

    The STL seems like it's heading that way too (std::transform, std::for_each, lambdas).

  2. #2
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by MutantJohn View Post
    Why is functional programming not more popular in C++?
    I dunno, my C++ has a lot of functions in it, most of the time it's quite functional...


    Quote Originally Posted by MutantJohn View Post
    My question is, why aren't functional patterns more popular in C++?
    A lack of enforceable tail recursion is a pretty serious drawback, and as much as I love RAII, lifetimes being fixed to blocks also presents a serious conflict.


    Quote Originally Posted by MutantJohn View Post
    I'm reading the wiki page on monads right now because I'm determined to implement the Maybe monad just for fun this weekend and I'm just thinking, why isn't this done more?
    Because in spite of not being the latest hipster rage, sentinel values are easier.


    Quote Originally Posted by MutantJohn View Post
    I think C++ is probably the best candidate to realistically carry functional programming right now.
    Is it? In my experience, it's much nicer to use the features you speak of in Lisps and Haskell.

  3. #3
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    It looks a little bit ugly in C++ and you end up writing a lot of code for nothing.
    (Also, without lazy evaluation, a lot of the interesting idioms do not translate properly.)

    Consider a 'textbook' example, in Haskell you could express Quick Sort like this:
    Code:
    quicksort [] = []
    quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
      where
        lesser = filter (< p) xs
        greater = filter (>= p) xs
    (Disclaimer, this is not a 'production ready' sort you would normally use in Haskell, but it looks beautiful and is sufficient for small cases.)

    Now you could, in theory, write a similar version in C++ but a normal array version looks better and is orders of magnitude faster.
    This might improve in future C++ standards with some variant of lazy ranges, though!

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Angola
    Posts
    8,445
    Quote Originally Posted by MutantJohn View Post
    The STL seems like it's heading that way too (std::transform, std::for_each, lambdas).
    There's your answer right there.
    C++ strength is in its ability to adopt your paradigm of choice; not through the language core, but by the expedite use good libraries (standard, or not).

    Quote Originally Posted by MutantJohn View Post
    Why is functional programming not more popular in C++?
    Some constructs are very popular in C++, as illustrated by the standard library. And Boost adds a number of other good ones. They are all used extensively, I'm sure, by those who are aware of their purpose and find a use case for them. C++11 in fact only standardized a subgroup of what has been a longtime practice in C++.

    However, the problem with the high level functional constructs is that they'll seduce you into thinking they are the best pattern for a given problem, when sometimes other approaches may be simpler and easier to manage. You can observe this on programming languages that more tightly integrate functional programing with other paradigms. For instance, the excessive and often made-complicated use of such constructs as list comprehensions, maps and lambdas on Python, being one of the most common anti-patterns in this language despite all the advise floating around.

    There's a sharp distinction that must be made between a program being executed and a program being developed. A program being executed doesn't care how it is being executed, as long as its purpose is achieved and its requirements are met. For this reason, a developer should always code their programs knowing that they will never be executed, but they will always be maintained.

    Function objects and sentinels can take the role of monads in almost all cases you'll come across. On those cases, introducing an explicit monad pattern in your code is hard to justify in a non-pure functional programming language; it offers no practical runtime advantage and comes at a maintenance cost that may not reflect on you presently but will reflect on you in the future when you get tired of monads (and you will!), or anyone else who needs to read your code and become familiarized with an alien pattern to the programming language. Like so many other high-level constructs (in functional programming and elsewhere), the choice of whether these constructs are acceptable should be made based on how well they fit the very structure of the problem being solved and the rest of the problem domain. Unfortunately, because software analysis is a dying art, decisions are made ad-hoc that then need to be carried on to other parts of the program which didn't need the complication.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    For instance, the excessive and often made-complicated use of such constructs as list comprehensions, maps and lambdas on Python, being one of the most common anti-patterns in this language despite all the advise floating around.
    This line really stuck out to me. I'm surprised that something like a list comprehension or a lambda would be considered an anti-pattern.

    I do agree, though, about the monadic pattern being an over-complication in most cases.

    Because in spite of not being the latest hipster rage, sentinel values are easier.
    This made me lol.

    Function objects and sentinels can take the role of monads in almost all cases you'll come across. On those cases, introducing an explicit monad pattern in your code is hard to justify in a non-pure functional programming language; it offers no practical runtime advantage and comes at a maintenance cost that may not reflect on you presently but will reflect on you in the future when you get tired of monads (and you will!), or anyone else who needs to read your code and become familiarized with an alien pattern to the programming language. Like so many other high-level constructs (in functional programming and elsewhere), the choice of whether these constructs are acceptable should be made based on how well they fit the very structure of the problem being solved and the rest of the problem domain.
    This is also really, really good advice.

    Someone wrote a Validator functor in JS and I have been using it as a means of object validation. This convenient for a couple of reasons. The first, the JSON blob looks identical on both sides (client and server) so the same validation routines can apply to both cases. Second, it aggregates errors when you use it properly.

    But using it in a useful context is pretty cumbersome and introduces some very needless overhead. It's not like performance is an issue but I think you might be right about it being a type of anti-pattern. I think I should revisit that code because while I really do enjoy the error aggregation, it isn't the most maintainable solution around and definitely needs to be looked at again.
    Last edited by MutantJohn; 08-14-2016 at 08:56 AM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,550
    Quote Originally Posted by MutantJohn
    I'm surprised that something like a list comprehension or a lambda would be considered an anti-pattern.
    Mario F. referred to "the excessive and often made-complicated use of such constructs", but unless the normal and reasonable use of such constructs tends to have overall negative consequences, they are not anti-patterns in themselves. At best you can say that such poor usage is an anti-pattern, but I don't think that's the right usage for "anti-pattern".
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    That's interesting. As an aside, here's an implementation of a Just (partially). I'd welcome any pointers/tips on it.

    So, because I'm still relatively inexperienced, when Mario said, we write code for maintainability, are monads/FP approaches really just more trouble than they're worth? I could easily see how some monad stuff would confuse other developers. It also makes bringing additional coders to the team _that_ much harder. *sigh* Sometimes they make sense but even when I'm explaining it to people I'm just like, man, this _is_ confusing.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, I'm done wasting my time implementing FP stuff! I found this: GitHub - beark/ftl: C++ template library for fans of functional programming

    There's already this massively awesome library out there. Okay, so functional programming _can_ be done in C++ and it doesn't seem like the worst thing ever.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How efficient is functional programming C++?
    By MutantJohn in forum C++ Programming
    Replies: 19
    Last Post: 01-25-2016, 09:35 PM
  2. Functional testing
    By g4j31a5 in forum Tech Board
    Replies: 15
    Last Post: 03-22-2012, 01:54 AM
  3. functional derivation better?
    By CodeMonkey in forum C++ Programming
    Replies: 3
    Last Post: 08-16-2007, 12:57 AM
  4. Functional programming languages... r they really functional?
    By code_mutant in forum C++ Programming
    Replies: 10
    Last Post: 02-25-2004, 05:29 AM
  5. functional dependencies
    By DMaxJ in forum C++ Programming
    Replies: 10
    Last Post: 10-23-2002, 07:07 AM

Tags for this Thread