Why functional programming doesn't catch on
I think that the actual reason for the limited adoption of FP languages is exactly that: the way the advantages are formulated and exemplified are completely obvious and compelling to their proponents, but those same explanations and examples utterly fail to convince most software engineers, because they simply do not appeal to the problems they are confronted with in their daily line of work.
I think this hypothesis is best exemplified by the seminal paper Why Functional Programming Matters. This paper sets out to
and then goes on with explanations like[..] demonstrate to the 'real world' that functional programming is vitally important,
[listing of advantages]
Such a catalogue of 'advantages' is all very well, but one must not be surprised if outsiders don't take it too seriously.
We must must find something to put in its place - something which not only explains the power of functional programming, but also gives a clear indication of what the functional programmer should strive towards.
and applications to things like the Newton-Raphson approximation and tree pruning in artifical intelligence.The definition of reduce can be derived just by parameterising the definition of sum, giving
(reduce f x) nil = x
(reduce f x) (cons a l) = f a ((reduce f x) l)
[I'm inserting an intentional dramatic silence here, in which you can see my facial expression turn to complete astonishment]
Now how in heavens name can one expect to convince the average software engineer of the tenets of functional programming with these kinds of examples? If it does one thing, it is scaring people away by seeming unnecessarily difficult and academic.
Every introduction to a programming language shows you the recursive method to calculate Fibonacci numbers. It's abstract, many people do not relate to it very well, but it's only a single example. However, the documentation for FP languages seem to consist solely of these kinds of highly mathematically inspired examples. No 'Address' class to be found there. Hasn't anyone written a functional equivalent of the Pet Store application to demonstrate the power of FP for the regular work that most of us do?
People that want to improve the world often overlook one fundamental problem: you cannot improve the world just by being right. You need to convince others of that fact if you want to exert influence. If you cannot convince them, find out why you cannot convince them. I think there is a bright future ahead for functional programming, as soon as someone stands up to convince the masses.
As not everyone reads the comments, I would like to highlight a few points made there:
- The article I quote is 25 years old and was directed to people in academia. It would not be fair to conclude that all FP documentation is that hard to understand for someone without an academic background.
- There are deliberate attempts at displaying the 'real life' value of FP, for instance in Real World Haskell and Practical Common Lisp.
- Several people assert that FP is catching on, but it just isn't very visible (yet). This may be because those that use it consider it a competative advantage
I'd really like to learn more about it but it's hard to catch on without any real-life (well programming real life anyway) situations
FP languages are fundamentally different, and they aren't worth learning if it only solves some edge cases.
And that's where mixed languages come into play. Mixing imperative languages with functional languages to combine the best of both worlds.
I intend to try and create those kinds of useful, non-abstract examples, but I'm not sure whether I'll succeed. I certainly don't think they will be simple. One of the main points that the quoted article makes is that FP allows for new ways of modularizing your code. To show the power of that, you need an example that requires modularization and that almost certainly means a large bit of code. Another major argument in favor of FP is the way immutable data and side-effectless functions prevent bugs, but to demonstrate that, you need an example with an insidious bug, which is hardly ever simple. Those same aspect mix very well with concurrent programming, but I think demonstrating the advantages in concurrent programming also requires a complex example.
I fully agree with H!GHGuY: mixed languages are the key to the adoption of FP languages. I have developed and interest in Scala, which I think looks extremely promising.
Real World Haskell is a book about the purely functional programming language Haskell and tackles problems such as parsing, web programming, databases, and GUIs.
"Every introduction to a programming language shows you the recursive method to calculate Fibonacci numbers. It's abstract, many people do not relate to it very well, but it's only a single example. "
The Fibonacci example (but also factorial) is often used as a concrete example of the language's syntax. Since functional programming languages are centered around functions, what could be a better way to show how to define them? You could say Fibonacci and factorial are the Hello World of the functional world.
"Heck, even C# supports lambda expressions nowadays!"
Not only that, it even has monads!
However, I have a tough time seeing where is FP *not* catching on. I often find co-workers using functional patterns in their code without even realising it. It is getting more difficult to find languages that do not have (or plan to support) advanced FP. When Java and .NET decide to start supporting FP concepts, you've got to wonder who thinks FP hasn't caught on.
Why not contrast with how FP languages are introduced in 2009. See e.g. Real World Haskell: full of web, gui, database, concurrent servers, and even bloomfilters for fun. All in an introductory text.
The programming universe of 2009 is very different to that of 1984.
I am enjoying the adavantages because I went out and learned functional programming and discovered for myself what the advanatages are.
I (and my team) have developed a substantial, real world, commercially available and purchased by large companies, business application in F#. The win is that there is a reduction in code written from 4 to 10 times depending on the nature of the task. We know this very specifically because we had some historical code that we re-wrote in F#. The code is also significantly more maintainable and more extensible.
Of course this gives us a competitive advantage. So maybe it is good that most are not convinced. I have this secret weapon all to myself
Thank you, that link looks promising.
I am convinced . The point of the blogpost was an idea on why many others do not seem convinced.
The example may have been unfortunate, but I intended it as an (exaggerated) example of what documentation of FP languages tends to look like. I cannot take a look at Real World Haskell without buying it; do you know of other Haskell examples that would falsify my hypothesis?
I intended to say that it is all and well that Fibonacci may be found in the documentation for *any* language, but that the documentation for FP languages seems to consist solely of that kind of mathematically inspired examples.
About the documentation part, well, yes... it might be lacking in a few areas, but for the Haskell community there is an interesting proposal on fixing it.
About your reply to dons regarding the RWH book, you don't have to buy it since it can be read for free. I already linked to it inmy earlier comment.
Thanks, I overlooked the online version of the book.
<a href="http://www.ternarysoftware.com/blogs/2009/02/21/playing-with-haskell-http-server/">Playing with Haskell - HTTP server</a>. And there are may other examples, especially lately.
On the other hand, there are still FP people out there who would just as soon you <i>didn't</i> think of FP as a great tool: I'm thinking here of Paul Graham and the whole "FP as secret weapon" meme.
Finally, there are a lot of people who really aren't that concerned about how practical FP is, they're just interested in for abstract mathematical aesthetics, blah blah blah. (I'm probably guilty of this, but then I teach at a liberal arts college, so I'm allowed .) "Avoid success at all costs" is the unofficial slogan of (at least a certain crowd of) Haskellers.
What's really interesting, however, is that many of the real practical advantages of FP arose out of this very lack of concern for practical utility. This is the "unreasonable effectiveness of mathematics" phenomenon described by the physicist Eugene Wigner. Perhaps the best strategy to find deep, long-lasting and profound advantage for real-world work is to take this seemingly paradoxical approach: studiously ignore practical considerations, on the one hand, in order to develop good theory; then, later, turn back to apply the more powerful tools you discover that way. This strategy has worked for mathematics for thousands of years, after all, and the overall dialectical process has been institutionalized in the disciplinary structure of pure and applied mathematicians, scientists and engineers that have brought us modern technology. Perhaps we shouldn't be surprised if this structure evolves in computing as well.
" [RWH]cover[s] the same amount of material the examples cover in another more mainstream language would have taken several more pages if not multiple volumes. How many books cover file processing, regex, parsing, network programming, we programming, system programing, GUI programming and 2 different concurrency mechanisms while teaching a new language all that in around 600 pages "
So I think we have a constructive proof that the FP community is taking practical teaching and application very very seriously. We're all about pragmatics.
But take a loop, take any program fragment. The FP approach can be thought of as asking and seeking ultimate questions of program parameterization. If I write a loop, why can't I pass it the body of the loop as a parameter? Why can't I pass a portion of the body as a parameter so I can use it elsewhere?
Recall that one of the earlier major OO languages, Smalltalk, did and does have FP constructs tied to its Sequence classes. That subsequent OO opted to abandon these and other dynamic constructs was a step backwards, not an improvement.
BTW, Java may "stomp" on other languages but its primacy isn't without significant question in certain fields. Few people working numerics would give up LAPACK, or LINPACK, or NAG. Java has issues with bare hardware. Java's libraries are ossified about a certain way of moving data around which may not lend itself to new ways of data management, including ones where the relational database no longer plays such an important role *especially* for big datasets. Java can be awkward to use in mixed (programming) language settings.
I'm pessimistic that producing "practical packages" in FP will turn the tide. We have those already, as the writings of Paul Graham show (although he speaks about LISP). And there's success to be had on a big scale, as Ericsson's Erlang demonstrates. I think this is about the nature of programmers committed to The Way They Now Know How To Do Things rather than anything about FP.
Many in the industry simply aren't intellectuals. It's not anti-intellectualism: it's non-intellectualism. If FP is really only for intellectuals, then everyone writing in favour of it is mostly preaching to the quire.
Moreover, pragmatism cannot 'infect' an industry: capitalist markets force industries to be as pragmatic as possible. However, as FP has distinct advantages, pragmatism includes FP.
I disagree. It is the anti-intellectuals. Children can learn pure functional programming. In fact, both of my two have - I put their standard well above that of my former IBM colleagues bashing away in their Java IDE and they are just normal kids. I know of other children who have done same.
Functional Programming has caught on quite a lot. To the extent that it hasn't is the same extent to which pragmatism has indeed corrupted the faculties of reason (PS: pragmatism doesn't mean what you think it means).
Also, AFAIK it also implies being able to declare anonymous functions, which make it possible to do memoization and other cool generator-like stuff
Another very useful thing is to be able to collapse the five-ten lined loop into one line, when all you want to do is iterate of one object and either return another (map), check if some or all of the items meet a test (filter) and so on.
These are pretty practical things, all of them.
See Eugene Lazutkins very good (and practical) blog on some use-cases;
Great post! I was unable to find your email address, which is why I'm submitting this request here. I was wondering if we could get your permission to feature this piece in our JavaLobby Newsletter. It will be going out tomorrow morning to approx 93K subscribers.
If you're interested, feel free to reach me at firstname.lastname@example.org.
As a non-FP man, this seems like an insightful blog.
FP has always had something almost mythical to me: it seems extremely useful at things that I don't understand and am not required to understand for my work. It might be useful to me, but I wouldn't know how or where to look. And as soon as I'd say that out loud, I'd have people telling me about learning a new language that I cannot use in my work environment such as Haskell.
Sure, I could spend a lot of time understanding it all and only then find out its usefulness, but it would require a lot of time, which I don't have. I need to be convinced quickly that every hour I invest in learning something new will be payed back over a reasonable amount of time or I'll defer learning until I'm forced to.
Your comments are exactly the kind of snobbish, elitist and excluding comments that hold back progress. You might have the best tool / language / technique / etc. in the world, but when you belittle people who don't use it / understand it / etc., this perfect thing will hardly ever get used because you drive people away from you and as such, it. You might be very good at software engineering, but you, sir, suck at people skills. If you enjoy being right and all alone in a high and mighty tower, be sure to keep it up.
1. I work alone, pretty much.
2. I work on a lot of projects quickly, and when I have a bug in one of them, it's very easy to debug
does something you don't like, it's incredibly easy to debug.
Break in foo, did I get the data I expected? What did I send up the stack?
Maybe I'm just way too un-fancy about this programming stuff, though, but why not just say
"FP is really easy to debug since all those side effects are gone" ?
I am trained in OOP, and it took about a year to change my hate towards FP (Haskell) into a deeper understanding of the merits of FP above OOP. Current OOP languages are really dumb once you know about what you can easily achieve in FP. Note that some OOP design patterns are direct part of the FP paradigm.
Switching from pure OOP to FP is a pain, but switching back to pure OOP once you've learned FP is a pain too.
The fp community consists of people who don't shave themselves, don't know about fashion and are generally a few times smarter than the average programmer. Ok,ok, not always true. I mean that fp people are generally clever people that love to explore new algorithms and exotic techniques. They tend to love mathematics. This means that there examples and their research is less accessible. Like the author of the blog post I feel these examples are less down to earth.
It takes you time to learn the fp paradigm. To start off, you could study functions as a first
You could then move on to Haskell, real world haskell might be a good resource.
Programs written in Haskell tends to be several times smaller than there pure OOP counterparts. This is better for maintainability, testability and other -illities.
Also, the rise of multi core systems and the death of concurrency by threads and locking mechanisms opens the way for languages like Haskell, since multi-core programming is an easy piece in u pure functional language.
It is possible to use FP with side effects.quote: Steven G. Harms"FP is really easy to debug since all those side effects are gone" ?
It might be unreasonable to expect to learn new concepts within the smallest time span possible and expect to reap the most benefit. Learning costs time.Sure, I could spend a lot of time understanding it all and only then find out its usefulness, but it would require a lot of time, which I don't have. I need to be convinced quickly that every hour I invest in learning something new will be payed back over a reasonable amount of time or I'll defer learning until I'm forced to.
For example, ask yourself, how long did it take you to become a good imperative programmer? If possible, try to dig up some old code from when you were just a beginner (say, 1 year after you started programming) and compare it to something you have written recently. Probably you'd notice you have grown a lot as a programmer.
Learning a (total) new concept such as functional programming and to fully benefit from it also takes a lot of time. You cannot expect to be able to master it within a small time frame, just like it is impossible to completely convince someone of its benefits with just a few sentences. Only by undertaking the journey to understand (parts of) the concept one can convince oneself.
The barriers to Functional Programming are the many preliminaries. Functional languages often have a syntax deviating from mainstream languages. While it is a minor problem, it does scare off the new people. The different syntax, however, suits the functional paradigm, just like (domain specific) languages as SQL and LINQ have a syntax suitable for querying data. Learning the syntax is learning to read.
The next barrier is to understand what you have read. What does it mean? For the imperative world, most of us here already have a certain mental model of how the computation takes place, namely by executing statements step by step, altering a global state. In the (purely) functional world, the model of computation is nothing more than a certain way of evaluating expressions, reducing them to simpler expressions. This process resembles what we did in our math classes (algebra) in high school, where we simply replaced variables with their values. Learning this model is needed to be able to understand what's going on.
But this is not all there is to it. Being able to read and understand a language, does not automatically mean we can express our thoughts in it, or at least not very well. People learn to express themselves through practice. By building small programs one after another, first by copying examples, then by altering them, we develop a deeper insight.
The problem here is that people often want to create something tangible and cool, i.e. something involving I/O such that a running program's behaviour is observable (other than your computer box getting hot). A program performing I/O is a somethig that alters some external state. This does not directly fit into the functional programming model and thus I/O has always been a bit tricky.
Even in Haskell, where I/O actions have beautifully been modeled using monads, explaining how I/O works is not something you want to burden a beginner with. This puts us in a dilemma. We want beginners to play and create cool things, but we don't want to overload them with all the nitty details. The unfortunate result is that I/O (and monads) are introduced late in books and tutorials (so no "Hello World" as a first greeting).
The challenge perhaps here is to present a simplified view on I/O, such that we can introduce it earlier, and revisit I/O when the beginner has become more familiar with FP. (You might compare this to teaching Bohr's atomic model in chemistry class before teaching the orbital model.) On the other hand, give I/O to beginners too early and they may stray off the path to the Dark Side, falling back to their old behaviour and solving their problems in their old and customary, stateful way.
Now, I noticed I kinda drifted off so I'll stop typing for now. If you want a (3 hours) Haskell crash course, you could watch Simon Peyton-Jones' talk "A Taste of Haskell" (part 1 [FLV]) (part 2 [FLV]) (PDF slides).
Java = Spice Girls, New Kids on the Block (marketing driven drivel)
C/C++ = Tool, Metallica (causing of much angst, though not so bad for it's purpose)
Asm = Rap (potentially interesting, but lacking dimensions)
Prolog = Beethoven
SmallTalk = Mozart
Lisp = Bach
Stateless programs; No side effects
Real-world programs are all about side effects and mutation. When the user presses a button it's because they want something to happen. When they type in something, they want that state to replace whatever state used to be there. When Jane Smith in accounting gets married and changes her name to Jane Jones, the database backing the business process that prints her paycheque had better be all about handling that sort of mutation. When you fire the machine gun at the alien, most people do not mentally model that as the construction of a new alien with fewer hit points; they model that as a mutation of an existing alien's properties.
When the programming language concepts fundamentally work against the domain being modelled, it's hard to justify using that language.
Concurrency; Plays extremely nice with the rising multi-core technology
The problem is just pushed around. With immutable data structures you have cheap thread safety at the cost of possibly working with stale data. With mutable data structures you have the benefit of always working on fresh data at the cost of having to write complicated logic to keep the data consistent. It's not like one of those is obviously better than the other.
Programs are usually shorter and in some cases easier to read
Except in the cases where they are longer and harder to read. Learning how to read programs written in a functional style is a difficult skill; people seem to be much better at conceiving of programs as a series of steps to be followed, like a recipe, rather than as a series of calculations to be carried out.
Productivity goes up (example: Erlang)
Productivity has to go up a lot in order to justify the massive expense of hiring programmers who know how to program in a functional style.
And remember, you don't want to throw away a working system; most programmers are not building new systems from scratch, but rather maintaining existing systems, most of which were built in non-functional languages. Imagine trying to justify that to shareholders. Why did you scrap your existing working payroll system to build a new one at the cost of millions of dollars? "Because functional programming is awesome" is unlikely to delight the shareholders.
Imperative programming is a very old paradigm (as far as I know) and possibly not suitable for the 21th century
Functional programming is very old too. I don't see how the age of the concept is relevant.
Don't get me wrong. I love functional programming, I joined this team because I wanted to help bring concepts from functional programming into C#, and I think that programming in an immutable style is the way of the future. But there are enormous costs to programming in a functional style that can't simply be wished away. The shift towards a more functional style is going to happen slowly and gradually over a period of decades. And that's what it will be: a shift towards a more functional style, not a wholesale embracing of the purity and beauty of Haskell and the abandoning of C++.
I build compilers for a living and we are definitely embracing a functional style for the next generation of compiler tools. That's because functional programming is fundamentally a good match for the sorts of problems we face. Our problems are all about taking in raw information -- strings and metadata -- and transforming them into different strings and metadata. In situations where mutations occur, like someone is typing in the IDE, the problem space inherently lends itself to functional techniques such as incrementally rebuilding only the portions of the tree that changed. Many domains do not have these nice properties that make them obviously amenable to a functional style.
See also http://importantshock.wor.../01/18/jquery-is-a-monad/
tenant screening services
I likes stuff like this website and this has now given me A few inspiration To succeed, so Bless you. =)
how to repair motorcycle fairings
Comments are closed