The masses agree with you, apparently. That's why they sit in their cubes all day writing the same god damn re-implementation of map over and over again
List<String> result = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
result.add(input.get(i).toString());
}
instead of input.map(_.toString)
because functional programming is confusing.I still don't understand why recursion is confusing to learn, as for me it was obvious from day one. Then again I am good at maths.
Additionally, I had lots of fun doing Caml and Prolog when I was at the university.
So even though I tend to do the typical boring enterprise JVM/.NET/C++ stuff, I do welcome the FP contamination of those ecosystems. :)
However on my last project, I had to rewrite some LINQ stuff back to plain imperative code, because few people on the team could manage it (LINQ). :(
The solution using map is more intuitive, once you know what map is.
I agree with you, as well, that the functional style should be used far more often than is the case. I just think that one shouldn't assume that our way of doing things is inherently more intuitive, even if it is most often better.
I think we're wrong on one thing. Personally, I think imperative code is more intuitive. It matches how people think of operational behaviors.
For a 20-line program that will never grow, I'd rather see an imperative straight-line solution. FP wins when things get a lot more complex: various special cases and loops within loops. Stateful things compose poorly. Debugging a 300-line inner for-loop is no fun. Functional programming, done right, means people factor long before it gets to that point.
Factories and Visitors prove what hellishness comes into being when one doesn't have those functional primitives, but this does not make the superiority of FP intuitive or obvious.
Now, OO is so variable in definition that it's very hard to know exactly what people mean. There's the good OOP (Alan Kay's vision; encapsulate complexity) and then there's bad OOP (overuse of inheritance, auto-generated classes, Factories and Visitors).
One can conceive of core.async as an OOP win in Clojure; lots of complexity (macroexpand a go block at some point) is being abstracted behind the simpler interface of a channel.