The article is conflating between two fundamental but different concepts;
1) Semantics of Language Constructs (part of Solution Domain) - These are just tools used to express any intention. You can make this as simple or powerful as you want.
2) Semantics of Programmer Intentions (part of Problem Domain) - These are the actual intentions expressed via a language according to the programmer's needs. Obviously no amount of language power can anticipate/provide-for all possible intentions.
In order to map (2) onto (1) we model problem approaches into distinct categories like Computation models (eg. Procedural/OO/Functional), Architectural models (eg. Monolith/Client-Server/Component) etc.
But the correctness of the above mapping depends only on the usage of rigorous formal logic to assert the intentions explicitly. This is why Dijkstra invented a simple language like GCL and taught how to verify your intentions in code using invariants/preconditions/postconditions and logical rules to mechanically transform a postcondition to precondition and thus derive a program based on intentions (expressed unambiguously as mathematical specifications).
A programming language can support the above at compile-time using types and/or at run-time using contracts but the fundamental problem of mapping Intentions -> Code can never go away. Hence this is what we should focus on learning. Once we are clear on this, mapping it onto any language (simple or complex) becomes comparatively trivial.