I'm really tempted to write a blog post about "fake functional".
The thing is, I really like functional. I really like Haskell. But most of the things that I like about Haskell aren't present when you rip things out of it willy-nilly and drop it into a language not designed for those idioms. The thing I like about functional programming is the fluid composition of all those ideas, and just dropping "map" or "option" doesn't mean you've got the fluid composition. Jamming functional paradigms into languages where they don't compose like they do in Haskell is just fake functional.
I'd much rather work with a language in the space where it does provide fluid composition of its concepts then jam a foreign idiom into it and enter into a constant low-level war, where I'm likely going to have to roll out the Inner Platform gun to try to wrangle the language into being a bad imitation of another language. And that's a gun I want to be firing as a last resort, not using as my primary weapon.
Functional programming can mean a lot of things to a lot of different people so declaring something “fake functional” is difficult.
If we get down to brass tacks, functional programming is just solving problems by composing functions, if we want to talk “purely functional” then we’re making more promises regarding side effects and immutability.
So I’d hesitate to call anything “fake functional” myself, I suspect what we call functional languages are often just “languages that do a good job letting us apply functional programming concepts”, and languages that don’t do that well will certainly not feel as good to use as ones that do (if you like the ideas in functional programming that is).
So in a way I agree. I personally can solve problems in Elixir using functional ideas more easily than Ruby. At the same time I could absolutely write a mutable, side effect ridden mess in Elixir or some pretty respectable functional looking code in Ruby.
I think it’s more about what the tool encourages and makes easy for you to do than a binary functional/not-functional designation.
In contrast, I really like the simplistic functional elements added to a language, like the Java 8 stream API, but I feel like banging my head against a wall using scala with effects systems.
I actually like some of the things added; being able to write a map function that takes an already-existing function and applies it to an array con be more convenient than the for loop. Depends on the language, obviously.
What I dislike are people who get on a high horse about it, as if they're programming "functionally" and it's better than what everyone else in the language is doing. They're not "programming functionally", because they can't be, the language doesn't support it. A single map call is convenient. Sometimes you can put a couple of them together. Huge piles of code in imperative languages written in functional paradigms is a mess, because most of the putative advantages of functional aren't present.
The one that I notice the most is that the "functional" paradigm embedded in imperative languages creates a barrier against refactoring. Sometimes it is simply that all the noise and chaff prevents programmers from seeing through to the underlying essense, and simply not realizing that if you have a recurring pattern of mapping the same three functions over an array in multiple places that you can in fact refactor that into a function. Sometimes, though, it's just not possible to refactor properly through inner platform you've introduced. Sometimes, refactoring is possible, but requires bringing in yet more firepower to get around the inner platform, like defunctionalization. By the time you're defunctionalizing something (by necessity, not choice) because of your inner platform to do something that would have been 4 lines of code in the original core language if you'd just used that, you're in deep trouble.
And what's worse, people will call this good programming. It's just the functional programming equivalent of frameworkitis that you see in languages like Java. "We need all this machinery to program properly!" No. You don't.
The thing is, I really like functional. I really like Haskell. But most of the things that I like about Haskell aren't present when you rip things out of it willy-nilly and drop it into a language not designed for those idioms. The thing I like about functional programming is the fluid composition of all those ideas, and just dropping "map" or "option" doesn't mean you've got the fluid composition. Jamming functional paradigms into languages where they don't compose like they do in Haskell is just fake functional.
I'd much rather work with a language in the space where it does provide fluid composition of its concepts then jam a foreign idiom into it and enter into a constant low-level war, where I'm likely going to have to roll out the Inner Platform gun to try to wrangle the language into being a bad imitation of another language. And that's a gun I want to be firing as a last resort, not using as my primary weapon.