Ask HN: Why is functional programming not more popular?
In the last couple of years I been getting involved with Elixir development and as of late starting get my toes wet with Scala.
The more I learn and use functional programming languages like Elixir, the more I'm convinced there is a significant advantage to using functional languages/paradigms specially in certain domains.
Yet, Functional programming is still regarded as a fad or fringe, curious to hear HN perspective on the matter.
36 comments
[ 2.3 ms ] story [ 90.0 ms ] threadFor some, FP is actually more natural. To them, it's a revelation and a freedom, and they can't understand why everyone else doesn't also find it to be wonderful.
That’s exactly what got me interested in FP. But after doing some serious work in FP, I must say typed FP really does help keep my mind more saner, knowing nothing’s broken in the product, with my changes here and there.
Of course, TDD helps in OO/imperative languages, but with typed FP you get that almost for free.
And also I'm pretty sure TypeScript has union, intersections, tuples, record which are pretty much ADTs.
Together with
* Imperative/OOP programming works. All kinds of cool software have been built using those paradigms.
that means that few people have a pressing need to look into functional programming. Some who are curious do. Some of those love it and don't want to go back.
But there's nothing wrong with not doing functional programming!
And last
* Both C++ and Java have adopted (or stolen) quite a few things from functional programming languages.
The FP purist will say that it doesn't matter, but it really does. They stole those parts that get their users maybe a quarter the way to functional nirvana, but with very little effort. That's obviously enough to succeed.
> People think imperatively most of the time.
Most of the time people think declaratively. Heck, people dream, wish, and plan declaratively. They wouldn't even know how they got to their thoughts and dreams. They're just there instantly.
However, it's hard to make functional programming general purpose. There are some posts about it elsewhere, but iterative programming tends to make reasoning about the storage of different objects in memory quite a bit easier. Given how all abstractions are leaky anyhow, there will almost always eventually be some component that is easier to deal with using OOP. The inverse is not necessarily true.
There are some practical considerations here as well. While it's possible to make OOP-esque structures in functional languages, it's not trivial. Meanwhile, using a piece of functional code in an already OOP system generally isn't too bad - there is, once again, some syntactic sugar, but the scope tends to be clearer. Putting a bit of functional code inside say, a class, tends to muck with the usage and assumptions of said class less than putting a bit of OOP into functional code.
Depending on what you mean by "functional", this is not always true. Rust is essentially a functional language - in that, just like functional languages, it prevents you from mixing shared state with mutability; plus it heavily uses functional features like closures - but it makes it quite easy to reason about the storage of data objects.
I view OOP as basically mistaken, particularly wrt. choices like implementation inheritance as an "idiomatic" element of software design. And newer languages like Rust make the exact same choice there. But once you take the trouble to carefully "unpack" stuff like implementation-inheritance, even OOP is quite compatible with a functional paradigm.
Sorry, not parsing the last sentence - what do you mean by “he is not available to work at the company”?
There's FP as in, it isn't horrid C++/Java class-making with virtual functions and constructor boilerplate.
There's FP as in, hey we've got lambdas and are doing stuff with them (like chaining callbacks or using futures).
There's FP as in, a language that materially inhibits your ability to be non-explicit about what your code is doing.
So it might be good to be aware of what mechanisms by which FP provides a benefit. Much of it is, it's not horrid class-making and workarounds to do basic stuff the language should support. It's just half-decent language design. But then there's the matter of being materially or somewhat culturally being explicit about side effects. And these are two different aspects.
And many devs don't get the latter. They're kind of smart-sounding words and they'll agree with them if you say it, but they don't really get it.
And among people who don't really get it, there's also the FP people who cargo-cult it. I'm talking about the people that rewrite their for loops in terms of map/reduce/std::transform or what-have-you, because they're crazy people unwilling to make mutable local variables. (Kind of like how some will never make a function-local goto statement.)
I've dabbled in some FPish languages, most lately Prolog (which I loved) and ML. I do a lot of graphics programming, so was wondering how to do that with ML. Like say you have an 3D array representing colour pixels, and want to change a pixel's colour. It seems in FP either you make a new copy of the whole updated array, or use fiddly workarounds where you store the changes and actually do them at some later time.. Googling about it, I felt quite embarrassed for FP, since all the talks I'd seen present it as a mega-cool super-sophisticated best way of doing everything. And as if changing variable values is a barbaric sin. ..So, back to C to do graphics.
Situations like this, where large data structures must be repeatedly changed in small ways, which happens in a lot of domains I guess, seem tricky to do efficiently with FP!
I like OOP because it's like boxes where you can just plug one cable from one part into another. It's easy to write "contracts" in, as in assigning what object does what.
There are definitely flaws with this, in that it can get messy, but does FP solve it better? What exactly does FP do better?
https://m.youtube.com/watch?v=g1TsP60z2OQ
Two reasons:
Immutability guarentees that the variable name changes when the underlying data is changed. Therefore, we don't have to track complicated state through the program or in other threads and processes.
The type system catches many errors at compiletime. Fewer tests and easier to test. The trade-off is that the type system is slightly more complicated. Yes, it does have to be FP to handle this properly (type inference and higher order functions make it manageable).
2. Being a relatively new paradigm, less people understand where, when, how, and why FP fits. There is a lack of effective education over FP.
3. Having some radical jargons (e.g. HOF, recursion > looping) , FP brings fear of change. Especially, recursion > looping can only be applied to languages with gc, preferably those with tail call optimization.
4. FP's more universal virtues (immutability, pure functions, type system, no side effect) are not advertised enough compared to other virtues (recursion, hof).
Also, can't resist nitpicking about tail call optimization: clang/llvm and gcc implement it in a non-gc language (C), but meanwhile some FP language implementations lack it, at least Clojure does. So while there's more demand for that feature in the FP world and some FP languages like Scheme require implementations to perform this optimization, it's conceptually somewhat orthogonal to FP or GC.
Those concepts helped me avoid a lot of headaches without knowing that those are concepts of FP. Then there was a day where I just realized, "Oh, this is FP"
I guess people need to be educated, or experience themselves, the concepts, before hearing the word "FP" which mean less to them.
The examples provided in the internet needs to be more ambituous than mere chains of functions. They need to be "remaking rsync with minimum IFs" or "large scale React App without a single getDerivedState"
1. Shut up about monads. “Monads” sound like a bad D&D monster. No one cares about either of those things
2. Benefits sell, not mechanisms. Show me the benefits in a way that solves my problem without warping my brain around in the process, and I’ll buy it.
3. Every new paradigm has a ‘gap’ that must be overcome, a proverbial “click” of a new brain-circuit forming, before understanding/enlightenment is possible. This process is accelerated by direct experience, but slowed glacially by overly formal abstract presentations
4. Stop trying to show me how hip/smart/woke/l33t you are by spouting FPisms; that impresses no one, bores most, and makes you look like a poseur. Benefits, McCoy.
5. I love Scala, but it’s an acquired taste that didn’t happen overnight, and it started as a non-threatening “better Java” path that led to self discovery through refactoring. Please Give us space to breathe and languages that don’t cause Calculus 101 PTSD flashbacks.
Some good ideas eventually make it to mainstream / conventional wisdom because there's some second factor that brings them to the spotlight. For languages it might be a killer app, big corporate investment, etc.
In https://www.youtube.com/watch?v=QyJZzq0v7Z4 Richard Feldman puts up a (well founded IMO) argument that OO became accidentally popular because of C++. C++ didn't do OO well, nor was OO the main benefit of C++, it just happened to be something that came with C++.
I think it's mostly related to the "age" we live in. For the last two decades OOP has been the main thing. New problems arise, software is written differently now and a lot of development related things have been changing, so maybe/probably there will be a shift to FP.
That's my sole opinion, though.