The problem with monads is they are horrible without some form of syntax sugar. I like the metaphor of "programmable semicolon", but in languages without some built-in support, the "semicolon" becomes repetitive boilerplate which is more code than the actual operations happening in the monad.
I like the "do" notation in Haskell because it boils down the meaning of monads to the following:
Monads let you break the functional programming paradigm that a function should have the same value each time it is called. e.g.
do {
x <- getInput
y <- getInput
return x+y }
here getInput is called two times and each time it has a different value. When you now think about how this can happen in a functional language you have to understand what a monad does.
The heureka moment came when I learned about the flatMap in scala which is nothing else but the bind function in haskell ("just flatmap that sXXt") and voila thats how to use monads.