>Ah screw it I can’t finish this. I don’t know how to translate the steps without mutable state. I can either lose the ordering or I can say “then mix in the bananas,” thus modifying the existing state. Anyone want to try finishing this translation in the comments? I’d be interested in a version that uses monads and one that doesn’t use monads.

He's wrong and he completely misunderstood functional programming. It's not weird at all. Let's get things straight. First off there's a difference between functional programming and types. Monads are more of a type centric thing and also haskell centric. Haskell is a big part of functional programming but it's only one style. You can do functional programming without monads and also without type checking. Additionally type checking and even haskell-like type checking AND monads can exist in imperative languages as well (like rust.) Does rust having monads make it functional? No.

Second functional programs can be very very very very readable. It depends on how you structure it and your naming conventions. See example below:

list of data primitives (aka ingredients and tools):
cake
grease
flour
small_bowl
large_bowl
pan
whisk
salt
oven
cream
butter_milk
white_sugar
brown_sugar
walnuts

heatedOven = preHeatOven(oven, 175)
panWithGreaseAndFlour = putGreaseAndFlourInPan(grease, flour, pan)
bowlWithWhiskedIngredients = whiskStuffIntoBowl(small_bowl, whisk, salt, flour, baking_soda)
bowlWithSugars = mixStuffInBowl(large_bowl, white_sugar, brown_sugar)
bowlWithSugarsAndBananas = mixStuffInBowl(bowlWithSugars, bananas)
bowlWithAllingredients = mixStuffInBowl(bowlWithSugarsAndBanas, bowlWithWhiskedIngredients, buttermilk, walnuts)
panWithAllIngredients = pourContentsOfBowlIntoPan(bowlWithAllingredients, pan)
heatedPan = heatPan(panWithAllIngredients, heatedOven, 30)
finishedProduct = coolPan(heatedPan)

I mean that's so simple I can literally translate that into english:

Create a heated oven by heating an oven to 175 degrees.
Create a pan with grease and Flour by putting grease and flour into a pan.
Create a bowl with whisked ingredients by whisking salt, flour and baking soda into a small bowl with a whisk.
....

You get the picture... It's just real practical english tends to be less pedantic that's it.

Think about it this way. Let's say we live in an imperative world where we have an oven. We then heat the oven. Now in the imperative world the oven is destroyed and replaced by a heated oven. We only refer to the "heated oven" as an "oven" for convenience but in fact the original "oven" is actually destroyed as in it no longer exists.

In functional programming THE only difference is that the original oven is NOT DESTROYED. That's it. You have a heated oven, but you still have a reference to the original oven. But you don't ever need to refer to original oven if you don't want to. This makes English describing imperative processes more or less IDENTICAL to functional processes.

Another perspective to think about this is that in the English language we create the heated oven but the original oven is not destroyed but moved! The oven is now moved into a namespace called the past, we can only refer to the original oven by appending or prepending one of the many names and phrases of the "past" namespace to the oven! For example: The oven "before it was heated", the oven "from the past", the "original" oven,... etc.

So from that perspective then the only difference between FP and english is that variables once operated on, are moved to a different namespace. So literally just extra past-tense embellishment on English grammar is the ONLY difference.

It gets crazier than this. Is anything in reality really mutable? What does mutability even mean? We live in a universe where each instance of time is it's own namespace. The universe is a function of time. At t1 there is an oven, at t2 there is a heated oven. So really mutability is just syntactic sugar over immutability where just gloss over mentioning what time namespace we're in for convenience. Yes you heard that right. Everything is actually immutable and mutability doesn't exist. Our concept of "mutability" arises from language shortcuts we take and assumptions of present tense.

Either way from the examples this guy writes it's pretty obvious functional programming didn't click for him. He understands the rules like immutability and he sees all the crazy tricks and nutty types people associate with functional programming but he missed the big picture. Hopefully this explanation will let the concept of functional programming click a bit more with people.

There is in fact a deeper intuition for why functional programming is "better" than imperative programming. But that's another long explanation. Most people don't ever reach this point of realizing how functional programming is better. They could spend years doing functional programming and completely miss it. Instead they reach a state where they think functional programming is sort of a style of programming used to express intellectual arrogance with no practical benefits and they give it up and move back to imperative programming. Well, they are wrong and they missed a deeper understanding of a fundamental concept. If this sounds like you, I'm telling you... you missed the big picture.

Literally the OP is a picture perfect example of this. Completely missed the point of FP but spent enough time with FP to understand what a monad is, even though a monad isn't really technically an FP thing.