Is it the same issue as the infamous "monads tutorials" problem, where the understanding takes a lot of time to infuse but looks obvious in retrospect when it finally clicks?
The "monad" problem is worse; many of the "tutorials" were actively wrong about some critical element, often more than one. I don't think I've seen someone claim to have linear algebra "click" but be fundamentally wrong about it somehow.
One advantage of linear algebra is that it is, well, linear. Linear is nice. It means you can decompose things into their independent elements, and put them all together again, without loss. The monad interface, as simple as it is, is not linear; specific implementations of it can have levels of complexity more like a Turing machine.
Maybe I'm biased, but I really don't think so. Monads are quite a bit more abstract than the concepts in linear algebra. Linear algebra is both geometric and algorithmic and therefore very intuitive. Most of the difficulty people have learning linear algebra can be attributed to poor teaching methods.
That depends on the part of linear algebra. In an abstract function space when you start calculating dimensions of kernels and the like and get ready to make the jump to infinite dimensions, Banach spaces, and Hilbert spaces, it's about as abstract as monads.
Well, to be fair, functional analysis is not part of linear algebra proper. (If you want to get more abstract, you go to rings and modules and from there to category theory.)
Typically, linear algebra is understood to be the study of finite-dimensional vector spaces, so functional analysis is not necessarily part of it.
However, things like the vector space of polynomials of degree at most n, the vector space of all homomorphisms between two vector spaces, the dual space of a vector space, etc. are all concepts that belong to linear algebra proper yet are more "abstract" than just "computations with matrices".
LA is one of those topics that, to an extent, is built on a handful of core capabilities and concepts. Once you master those much of what follows are logical extensions or combinations of the previous. It goes on from there, but the value returned from the core material is wide reaching.
"whenever somebody gets a deeper understanding of monads, they immediately lose the ability to explain it to other"
I don't remember where I've read this but it still holds even today.
Well, you see, that's one of the problems... monad implementations don't have to be "containers", or at least not the way most people mean. This was one of the critical errors in many of the aforementioned "tutorials". IO, the quintessential monad, is not a container, for instance.
(A nearly-exact parallel can be seen in the Iterator interface. You can describe it as "a thing that walks through a container presenting the items in order"... and yeah, that's the majority use case and where the idea came from... but it's also wrong. What it really is is just "a thing that presents items in some order". It doesn't have to be from "a container". You can have an iterator that produces integers in order, or strings in lexigraphic order, or yields bytes from a socket as they come in, or other things that have no "container" anywhere to be found. If you have "from a container" in your mental model then those things are confusing; if you understand it simply as "presenting items in order" then having an iterator that just yields integers makes perfect sense. A lot of the Monad confusion comes from adding extra clauses to what it is. Though by no means all of it.)
The problem is telling people it's a container is "over describing" it. We don't need to hypothesize about that. We have the space suits and burritos to prove it is not a good didactic approach. It is not removing from the definition to simplify, it is adding to the definition, exactly as I carefully showed in my description of "Iterator". An Iterator is "a thing that presents a series of items". It does not simplify the discussion of Iterator to say "It's a thing that presents a series of items out of a container, but also, it doesn't have to be a container". It's not the first definition that's "overdescribing", it's the second.
Part of why Haskell appears like such an implacable curmudgeon is the predilection of its community to believe that users must grasp type and logic theory to use it.
They don't.
Just like they don't need to have a mental model of their computer to write software for it.
I've had good luck with explaining it as a characteristic of a programming language. In a language consisting of sequences of statements with bindings and function calls, we expect that
f(x)
is the same as
a = x;
f(a)
and the same as
g = f;
g(x);
That's the monad laws. Whatever craziness you want to put in the semantics, those are properties you probably would like to preserve in your language.
I'm no expert, although I think I remember that a Monad is basically just like allowing a sequence of statements to be executed. Like executing a code file ;)
Functional languages are really weird, for instance it's possible to switch line order of statements and the compiler will still figure out how to stitch that together. I think even JS in parts has or at least had that behaviour. (Actually that's useful when having mathematical formulas that are interdependent and you're too lazy to order them topologically by dependence)
On the other hand, just executing a sequence of commands in order to do I/O is only a normal thing to do since recently as far as I understand. The sweet spot for FP is IMHO something like React where state is strictly separated from the functions. (Imagine writing Hello World using Normal Maths)
(Please correct me if I'm wrong, which is probably quite likely ;))
It's correct but jargony. So in the category of sets there is a notion of product between two sets called the Cartesian product, and one can do a couple things to endow this product with an identity element, for example one might use {{}} as that object in the category of sets.
The claim is that in other categories, there might be other natural combinations between two objects, for example a tensor product of Abelian groups combined with the integers Z as unit, or a composition of two endofunctors into a new endofunctor F ∘ F combined with the identity functor.
So the idea is that a monoid is somehow a destroyer of this combination operation; a monoid in sets un-combines the Cartesian product M × M back into the set M, and indeed this is a function (a set-arrow) from the combined objects to the underlying object.
By having an endofunctor combined with a natural transformation from F ∘ F back to F (natural transformations are the arrows in the category of endofunctors) a monad is therefore doing exactly what a monoid does, if you replace the "pre-monoid" combination step of the Cartesian product with instead a new "pre-monoid" combination step of endofunctor composition.
The definition is correct. A monad is an endofunctor with return and join functions. Just like a monoid in the category of sets is a set with identity and multiplication.
One advantage of linear algebra is that it is, well, linear. Linear is nice. It means you can decompose things into their independent elements, and put them all together again, without loss. The monad interface, as simple as it is, is not linear; specific implementations of it can have levels of complexity more like a Turing machine.