> This is why it's common for languages to be multi-paradigm
I can agree with that. Yet I somehow perceive an opinion that it is not FP unless it is Pure FP (?). Like even a small amount of impurity can poison the whole well.
> Erlang […] whose internal functions are 'pure' .
Why is that a good thing? You can easily reason with mutable code on a small, local scope, yet the real hard part will be the interaction of all those messages. Sure, erlang has plenty of safeguards for those as well, but I don’t see what would be lost if local mutability would be allowed.
I think it's also true that on a small local scope it is easy to write a function that takes the old state as argument and returns the new state as result. I think that in some sense makes it easier to reason about the 'evolution" of the actor.
I'm not sure I can explain why I think it would be simpler that way, but perhaps it is that conceptually you can then "package" the logic of how the actor-state changes over time into a single (local) function.
You want to understand and describe how the actor-state evolves over time? Read and understand the logic of this single function, whose results depends only on its arguments. Note that such a function does not have any internal state itself, it calculates the new state for the actor, always the same way based on arguments the system gives it.
I think that's the key to understandability here, the programmer does not need to know and keep track of the state and where it is stored and how to modify it. The system/runtime gives the current state to them as argument. It is not hidden into some variables somewhere who knows where. It comes as argument to function local to the actor. It is part of the definition of that actor.
This is how Erlang works, right? Is there a specific name they use for such a state-evolution-function?
Joe motivated this by the 'let it crash' philosophy.
Processes are supposed to crash when something that isn't supposed to happen happens. Inside OTP, this presumes that the reason for the crash was an invalid message, as processes should be black boxes that only communicate via messages (Alan Kay's definition of OOP).
Statefulness inside functions works against this goal. AFAIK, SmallTalk had similar idioms of returning new copies data to be sent to objects.
In all other languages, I agree with you. I can read and understand 100 lines of someones else's Go code faster than 20 lines of my own Clojure. I write Clojure for a living.
I think some people who discovered functional programming after "Pure" OOP, where everything is an object, fell in love with it and got a bit too high on their own supply. But i don't think it's the majority.
Also, functional programming is harder than pure imperative or imperative+object imho, which help gatekeeping, and more impressive (again, only my opinion). There is also a lot a good ideas that (came from/were invented by/were introduced with) FP and are integrated in older languages. This is a perfect setup to have cult-like groups appears, even if the person they revere isn't as "into it" as the group is generally. Imho it's mostly young devs who are/were pretty good for their age group (and thus have a bit of an ego[0]), a bit noisy, and will grow up and be more welcoming in the future.
[0] which is understandable and reasonable, this is absolutely not a shot, i was one of you (lisp/CLOS fanatic instead of FP fanatic, but still) until i worked with people 100 times better than i. The "grow up" is a small shot though, but don't take this seriously :)
I am suspicious of claims that procedural, imperative programming is “easier” than functional programming: in terms of how quickly one can learn it, how accurately one can predict what a program does by reading it, and how accurately one can make a modification. Assuming two developers both of equal experience in their preferred paradigms and languages I expect the functional programmer will score higher in these cases.
The cost of functional programming is that it does take some training to write programs in this style that many people are not familiar with. And I think it’s that lack of familiarity that people are referring to when they say that it is more “difficult.”
Personally I can’t disagree that it is harder to learn if you are already familiar with procedural programming. It took me quite a few months of dedicated work to get productive with Haskell. It was a painful, as I recall, because I had to throw out all of the accumulated experience I had with a handful of other languages.
Now that I am productive with it though I don’t find it any more “difficult” than programming in C or JavaScript or Python. In fact I find it easier: I can rely on the type system and reason about my programs and how they compose instead of stepping through their execution. Functional programming demands that I debug my thinking rather than my program most of the time. The former takes less time in my experience and becomes less frequent the more experienced you become.
Functional programming is routinely taught to complete beginners. Languages like Scheme or (core) ML are very simple and you can do a lot with surprisingly few constructs.
However, Haskell is in a different league in my opinion. If you want to do anything meaningful, you need monads which add some layers of complexity.
I consider myself a very experienced OCaml programmer, and I've been working casually for more than a year with Haskell, but I'm still much slower in Haskell. It still happens to me that I need one hour to figure out how to use some monad transformers, or specific API, to do something that would take me 10 minutes in another language. Well, probably I still need more practice, but the learning curve is certainly much higher for Haskell than Python.
Sure the learning curve demands more but the payoff is worth it. Monads, despite all the tutorials out there, are not that difficult a concept... once you learn it. It's frustrating to teach because of this. Like most things in mathematics it takes some effort to learn and pays off in spades. There are a ton of abstractions you get with learning monads and the rules of how they compose are consistent. It goes a long, long way. I'm better for having gotten through it.
Most abstractions in other languages though? Ad-hoc mish-mash of half-baked ideas with no laws and poor specifications. Each one you learn is absolutely useless when moving to the next program.
Monads are the same everywhere you go. Just like algebra.
I can agree with that. Yet I somehow perceive an opinion that it is not FP unless it is Pure FP (?). Like even a small amount of impurity can poison the whole well.