I don’t do “functional programming” for a living. I don’t know how to code in Haskell or OCaml. What I have to say here is based on doing some research on the topic. I could be wrong on some points. Fair warning.
Functional programming is a programming paradigm. Certain languages implement this paradigm, but you can do functional programming in many languages not originally designed for it.
There are some central ideas which characterize functional programming. First is the idea that data is immutable. Normally, you’re free to change any data you like in your program. If you have an array of five items, and you want to change the third one, you simply do so. The result is an array of five values, the third of which is different from its original value.
Not so in functional programming. If you have the five member array, and you want to change the third item, you get an entirely new array, with the first two and the last two numbers like the original, and the third one altered. You can probably see where this will end up, if you extend it out for a program which does a lot of thrashing of its data.
You might ask why one would insist on such a thing. Consider the example where you have a value set early in a program. Later you change that value. Later still, you check the value. Is your code aware that the value was changed halfway through the program? Could be a problem when debugging your program.
And that appears to be the sole reason, as far as I can tell, for the insistence on making data immutable. If we never change the data, then we don’t have to worry about that part when a bug presents itself. Seems like kind of a paranoid reaction in preventing bugs.
Let me stop here and make a point. Bugs only happen when you do something dumb. Period. It’s not the user’s fault. You should have anticipated that they were going to do the least predictable thing. You misspelled that variable. You didn’t initialize this variable. Your loop counter is off by one.
Don’t get me wrong. I get bugs in my code. But every time I go to find out what happened, it’s always something I didn’t predict or did wrong in the first place.
Functional programming appears to try to prevent you from doing stupid things by insisting on an extreme condition in handling of data. If a variable shouldn’t change its value in the course of a program, then don’t change it. Duh.
Of course, there’s an escape valve which allows functional programmers to break the rules. It’s called “atoms”. Really? So you make a rule, then a way to break it. Why did you make the rule in the first place? Of course, atoms are an implicit acknowledgment that programs can’t survive without changing the data they operate on.
Another pillar of the functional programming pantheon is “pure” functions. These are functions which return the same value when given the same input. It’s a concept borrowed from mathematics. When your math teacher proposed a “function”, like f(x), it was always a mapping of one value to another via some rule. Input the number 2, and the answer will always be 4, no matter what.
I don’t know about you, but most of the functions I write work this way anyway. If the value return of a function varies based on data not passed to it, I keep a very close eye on that function, and look to possible side effects from it when debugging.
Another thing functional programming apparently insists on is no looping. Lots of recursion, but no looping. Ever write a recursive function? They’re a bear to write, a bear to debug, and they can freeze your browser (and your computer) for ten minutes, while you wonder what you did wrong.
It’s also worth noting that a recursive function (or loop) which “changes” the data in functional programming is liable to create millions of entirely new variables or arrays before it finishes. But the functional programmer gods have figured a way out of this. Instead of storing an array as an array, they store it as a tree. It’s called a “persistent data structure”. Instead of copying the whole array into a new array and changing that one value for a whole new array, you add a branch to the tree that references the placement of the earlier value and includes the new value. Sounds complicated, doesn’t it? As a programmer, you don’t typically have to worry about coding this. You use a library which implements it.
Of course, if you just allowed your data to be mutable, you wouldn’t have to use this storage library. I’m just sayin'.
Ever looked at Lisp or Scheme? It’s like that.
I have to say that some of this is what any good programmer ought to be doing in the first place. Making rules about it appears to be a concession to the idea that programmers code without paying attention to what they’re doing.