Hacker News new | ask | show | jobs
by xyzzy4 3669 days ago
I don't get why people would use functional programming for anything. It's both more difficult and slower.
8 comments

I use functional style in C++ with lambdas and iterators. It is nothing but slow. I use functional style in Rust. It's blazing fast. Huge body of problems can be handled by simple recursion but I've yet to see non-functional programmers use it. I don't know why.

Functional style is simply better and is applicable in many languages. Modern C++ is a great example. Throw away much of OOP clunkiness, use simple functions, win! (OOP has it's place but in small quantities and with moderation).

With respect to purity I'm on the sidelines. I think what's far more important is algebraic data-types, pattern matching and value-returning conditionals (values, not statements!). Rust has them and it is great and not pure.

> Huge body of problems can be handled by simple recursion but I've yet to see non-functional programmers use it. I don't know why.

Stack overflows.

"Functional" languages typically have tail-call optimization and heap-allocated frames. Maybe OOP is a workaround for these missing features...
Why doesn't your language have TCO?

"Nobody uses recursion."

Why doesn't anybody use recursion?

"No TCO."

Tail-call optimization eliminates those. Assuming your language provides it, and assuming you trigger it correctly. ;)

http://stackoverflow.com/questions/32164370/does-elixir-infi...

TCO eliminates some types of recursion. Not all of them.
Eliminates some types of stack usage, not "recursion".
A significant part of my work is in a technical/numerical computing domain where Fortran is still prevalent. Most students who now enter the field have a tendency to start with Matlab, or feel like they are doing something truly modern if they use C++.

For various reasons, I chose to use OCaml, and from my experience, the difficulty part is only true insofar as the learning curve goes. Once past that, FP-style problem-solving is spectacular in that the vast majority of time you spend goes not into the coding, but rather (a) thinking about what exactly your problem is, and (b) how to decompose and solve it. I can't tell you how many times in Matlab, people start writing code before they've even fleshed out (a) and (b), simply because there's so much drivel and overhead that one naturally tends to feel they're "getting things done" by jumping in and writing this code.

Once I had a sufficient grasp of OCaml concepts and syntax, I would find myself getting frustrated by how little code I might get done in a day. Upon stepping back and reflecting, that was because I had not worked my way through (a) and (b), and that is where the human thinking is really required. I have since been delighted at the utility of each line of code I write and am similarly annoyed by the low signal-to-noise of something like Matlab.

With respect to slower, I think my points above address "slowness" in terms of development time. In terms of runtime, it's very much a function of your choice of language/ecosystem and paradigms. If GC and typical functional overhead are a constraint in your problem domain, one can always bring over a functional style into modern languages like Rust, where performance and lack of GC are first-order design goals. But you can't tar all of FP with the label of "slow" any more than anyone can make a blanket statement that "solving matrix problems is slow". It just doesn't make sense.

Lastly, as others have pointed out, Jon Harrop's points refer to purely functional styles and languages. In the end, striving for functional purity may not make sense. To illustrate, one can easily drop into an imperative style where needed in OCaml, for example when doing I/O. I use this quite a bit. But make no mistake that adopting a functional approach where it makes sense can pay dividends.

I rarely use FP but I certainly see it's appeal for certain things.

I think the concept of immutability confuses people bit. It really clicked for me when I stopped thinking of it in terms of things not being able to change and instead in terms of every version of things having different names.

Functional programming from that perspective is like version control for your variables. It makes explicit, not only which variable you are accessing but which version of it.

The reason it seems like you need to copy a variable each time you modify is just to give each particular mutation a different name. Note that the compiler can optimize things. It doesn't need to keep every version in memory. If it sees that you are not going to reference a particular mutation, it might just physically overwrite it with the next mutation so that in the background "var a=i, var b=a+j", might run as something like "var b = i; b+=j";

First, functional programming is an umbrella term. This paper talks about strict FP, which is basically "no mutation", so I'll talk about that.

It's clear that some other aspects of FP, such as first-order functions, closures, etc are very useful in practice.

Immutability does have its advantages in that it supplies strong guarantees about what your code does. It avoids spaghetti code where everything can and does mutate everything else.

Myself, I tend to use whenever its advantages outweigh its inconveniences. Immutability is especially handy at interface boundaries.

I agree that immutability is very useful, but you don't really need any kind of FP to use immutability, do you?
If your data is immutable, in what sense is your code not 'Functional Programming?'

"It's OO, and it can't be both OO and FP."

Hmmm.

I was going to say the same thing; it's certainly possible to write immutable object oriented code
Indeed, it's more of a pattern.
You're confusing first-class and higher-order functions.
Programming is both an art and a science. Art here means we don't have a hard scientific recommendations for all important cases; we have to learn tricks of the trade and use subjective judgement; naturally our programs differ widely.

Art - as something subjective - also means opinions differ on difficulty and slowness. That's perhaps why downvotes - the statement like this presented as an objective fact draws enough scepticism from those who have different experience in the subject.

Difficulty - Only at first. Once you get over the hump and learn to think functionally, procedural/OO starts to look like a convoluted mess.

Slower - Optimize for developer time. Same reason most people write their backends in Python/Ruby instead of C++.

When it comes to expressing logic in small composable, understandable pieces, nothing else can compete.

Unfortunately, it does have the challenges listed in the OP, so it seems to make most sense where either (a) it is ok to leave performance on the table in the interest of clarity or (b) you create a little sandbox in which you use functional programming for clarity, and something outside your sandbox compensates for the performance cost.

React and Om are examples of (b). They let you write pure functions that return the entire DOM. Then, outside that sandbox, a DOM differ makes it so you don't force the browser to re-render the entire DOM every time.

I think it's also interesting to note that sometimes when choosing immutability as the default, which gives a slight performance penalty for basic operations compared to doing normal mutation, you end up being able to save lots of performance on a larger level. React wrappers in ClojureScript, such as Om, are a good example of this - since data is immutable, shouldComponentUpdate is automatically and trivially implemented for you, leading to oftentimes better performance than straight React. I reckon this would also be the case with the lock-free code you write in Clojure, etc.
There are cases where referential transparency is essential, so it worth tolerating all the FP issues to get there.

Also, there is a lot of cases where you need a total language with all its guarantees.