Pitfalls/Disadvantages of Functional Programming [closed]

Solution 1:

It's hard for me to think of many downsides to functional programming. Then again, I am a former chair of the International Conference on Functional Programming, so you may safely assume I am biased.

I think the main downsides have to do with isolation and with barriers to entry. Learning to write good functional programs means learning to think differently, and to do it well requires a substantial investment of time and effort. It is difficult to learn without a teacher. These properties lead to some downsides:

  • It is likely that a functional program written by a newcomer will be unnecessarily slow—more likely than, say, a C program written by a newcomer to C. On the other hand, it is about equally likely that a C++ program written by a newcomer will be unnecessarily slow. (All those shiny features...)

    Generally experts have no difficulty writing fast functional programs; and in fact some of the best-performing parallel programs on 8- and 16-core processors are now written in Haskell.

  • It's more likely that someone starting functional programming will give up before realizing the promised productivity gains than will someone starting, say, Python or Visual Basic. There just isn't as much support in the form of books and development tools.

  • There are fewer people to talk to. Stackoverflow is a good example; relatively few Haskell programmers visit the site regularly (although part of this is that Haskell programmers have their own lively forums which are much older and better established than Stackoverflow).

    It's also true that you can't talk to your neighbor very easily, because functional-programming concepts are harder to teach and harder to learn than the object-oriented concepts behind languages like Smalltalk, Ruby, and C++. And also, the object-oriented community has spent years developing good explanations for what they do, whereas the functional-programming community seem to think that their stuff is obviously great and doesn't require any special metaphors or vocabulary for explanation. (They are wrong. I am still waiting for the first great book Functional Design Patterns.)

  • A well-known downside of lazy functional programming (applies to Haskell or Clean but not to ML or Scheme or Clojure) is that it is very difficult to predict the time and space costs of evaluating a lazy functional program—even experts can't do it. This problem is fundamental to the paradigm and is not going away. There are excellent tools for discovering time and space behavior post facto, but to use them effectively you have to be expert already.

Solution 2:

One big disadvantage to functional programming is that on a theoretical level, it doesn't match the hardware as well as most imperative languages. (This is the flip side of one of its obvious strengths, being able to express what you want done rather than how you want the computer to do it.)

For example, functional programming makes heavy use of recursion. This is fine in pure lambda calculus because mathematics' "stack" is unlimited. Of course, on real hardware, the stack is very much finite. Naively recursing over a large dataset can make your program go boom. Most functional languages optimize tail recursion so that this doesn't happen, but making an algorithm tail recursive can force you to do some rather unbeautiful code gymnastics (e.g., a tail-recursive map function creates a backwards list or has to build up a difference list, so it has to do extra work to get back to a normal mapped list in the correct order compared to the non-tail-recursive version).

(Thanks to Jared Updike for the difference list suggestion.)

Solution 3:

If your language does not provide good mechanisms to plumb state/exception behavior through your program (e.g. syntax sugars for monadic binds) then any task involving state/exceptions becomes a chore. (Even with these sugars, some people might find it harder to deal with state/exceptions in FP.)

Functional idioms often do lots of inversion-of-control or laziness, which often has a negative impact on debugging (using a debugger). (This is somewhat offset by FP being much less error-prone due to immutability/referential transparency, which means you'll need to debug less often.)