I wouldn't call it either of those things. They are so general that people have a hard time getting them. That's all.
>That's what the "mumble mumble endofunctors" joke is getting at: sometimes they're a useful generalization, but more often they're a way to make easy things sound hard, or to make bad teachers sound smart.
That is not at all what the joke is getting at (and that doesn't even make sense).
Starting with the abstract just messes people up and gets them confused. You don't start throwing around Kleisli Arrows and endofunctors right off the bat.
They are easy to explain to 2nd or 3rd year math students.
The difference is in the audience's cognitive bias.
A (Haskell) monad has to be a (mathematical) monad. Haskell is counting on it not just to have certain function signatures, but to have certain properties - certain identities that it satisfies. This lets Haskell do some transformations under the hood. If you hand Haskell something that you say is a monad, and it doesn't satisfy the identities, you're going to get some really unpredictable results.
That's the part that's easy to explain to 2nd or 3rd year math students.
But, unless you're writing an application in group theory, as a programmer you don't really need a monad. You need something that will let you operate on a value that's in a Maybe, and therefore you need a monad. That is, you don't care about it being a monad for the sake of monads, you care about it as a way to solve a particular programming problem.
That's the part that's hard to explain to CS students. They just want to operate on a Maybe. They don't understand why they have to care about it being a monad, or what the connection is between "monad" and "a kind of smuggler that will smuggle this function in to operate on a value that's stuck in jail in a Maybe" (or whatever analogy they're using).
If you see a place my understanding can be improved, feel free to correct it...