As far as I know, one can create a denotational semantics for any well-defined language. In practical terms, you could pick, say, JavaScript and do a similar representation as explained in the article: Every “non-pure function” is evaluated to a description of the state change that is caused by that function.
What is different for approaches as mentioned in the article is that all denotations (what we represent the result of applying a possibly effectful function) of the formal semantics, are also values in the language itself.
What this gains us is hinted at in the article: We can now implement different ways to execute these effects (i.e., for different execution environments or testing) »as a library« (without modifying the language interpreter/compiler).
However, this flexibility seems to be primarily used by language/framework implementers themselves. Not by application developers. Library implementations of “effect systems” seem to create their own DSL for denotations (i.e., having their own IO type, maybe reusing some closeby syntax from the host language).
For application developers, in case of this article, it seems that the main improvement is that effectful computations are marked with an ! so they are easier to spot. Don’t get me wrong, I think that is very valuable for very little additional syntactic complexity, so it’s a great thing to do.
However, the more I look into this the less I buy into the whole “functional semantics” for side-effects argument. Immutable data is great, explicit dependencies are great, but those are about minimizing the use of side-effects, not about dressing them up.