I suppose one of the biggest parts of confusion here is that I'm mostly referring to the monadic programming here in the perspective of the compile-time representations inside of a compiler rather than in the exposed type systems of the languages that they compile. A compile-time representation of computation is a type that represents computation. Not every compiler author themselves think of their work as monads and build them in a way that follows the monad laws/use monad operators directly either, but the overlap should be obvious and a lot of classic and modern compile-time transformations (generators, try/catch, async/await) can be thought of as monadic transformers transforming from one class of monad to another whether or not they are actually implemented that way.

That's one level of confusion in this conversation so far. However, the other problem is that monads don't just mean "computation". (Arguably the Lambda Calculus is way closer to the metal and more accurate to describe as the abstraction of "computation".)

Monads are useful for describing "computations as values" but that's not what the abstraction is entirely for and thinking of monads only as "computations" is how you fall into the easy mistake to make that IO in Haskell is the only "real" monad. There are lots of monads in the wild (Maybe, Either, Promise, List, ...), some of which don't really describe computation at all. We love to mock it, but the technical definition of a monad is "a monoid in the category of endofunctors"; nothing about that is "computation" specifically. Computation is a handy shorthand, of course, but its confusing one of the trees for the rest of the forest sort of thing, mostly because Haskell's IO was the first time monad escaped as a term of art for the deep abstraction that it is.

There is an importance to the monad laws and the two monad "operators", more importance than "computation" as a shorthand for thinking about monads. These operators are called "multiplication" and "identity" in raw Category Theory, but in programming "identity" is usually called "return" and "multiplication" is often called "bind", "bind" is interesting because it also has a dual generally called "join" and "join" is sometimes called "flatMap" or "SelectMany". (Yes, that does point out that most list structures in every modern programming language provide monad operators and obey the monad laws. Lists are a monad.)

A dumber, better shorthand for monads may be "glueable". Monads bind things together in a way that two binds of the same type of monad results in just one monad. (flatMap two lists together and get one list back.) The power of monads is that you can keep gluing things together. Whether by "executing side effects" in a "computation runtime" like the stalwart IO monad or in all the "boring" ways of Lists and Promises and Maybe and Either (that mostly have nothing to do with "computations", except Promises, sort of). The big useful bit is that the Monad laws imply that you can do all this "gluing" in a stable way. That stable way also makes room for the means to transform from one type of Monad to another (Monadic transformers).

Monadic transformers are where some of the real power of the IO monad as an abstraction lives (and other monads in terms of compile-time representations): the idea that the "notation" doesn't matter so much as the end "glued" result. Imperative looking do-notation is the same sort of "glue" as a lot of individual calls to the Monad operators bind and return, transforming from one form to the other is "relatively" "trivial" because the Monad laws say everything should be fine.

There is a usefulness to the IO Monad in Haskell and it is an interesting way to "describe side effects to perform", but the whole of monads and monadic binding is a lot more than just the IO Monad and if you are defining monads to only mean "the IO Monad" you are missing some of their other usefulness.