Modular monadic semantics is a high-level and modular form of denotational semantics. It is capable of capturing individual programming language features as small building blocks which can be combined to form a programming language of arbitrary complexity. Interactions between features are isolated in such a way that the building blocks are invariant. This paper explores the theory and application of modular monadic semantics, including the building blocks for individual programming language features, equational reasoning with laws and axioms, modular proofs, program transformation, modular interpreters, and semantics-directed compilation. We demonstrate that modular monadic semantics makes programming languages easier to specify, reason about, and implement than the alternative of using conventional denotational semantics. Our contributions include: (a) the design of a fully modular interpreter based on monad transformers, including important features missing from several earlier efforts, (b) a method to lift monad operations through monad transformers, including difficult cases not achieved in earlier work, (c) a study of the semantic implications of the order of monad transformer composition, (d) a formal theory of modular monadic semantics that justifies our choice of liftings based on a notion of naturality, and (e) an implementation of our interpreter in Gofer, whose constructor classes provide just the added power over Haskell type classes to allow precise and convenient expression of our ideas. A note to reviewers: this paper is rather long. Short of resorting to “Part I / Part II”, the one way we see to shorten it would be to remove Section 4 and its Appendix B, which would amount to eliminating contribution (e) above. This would shorten the paper by about 12 pages.