Programming, wrote Dijkstra many years ago, is a branch of applied mathematics. That is only half of the picture: the other half is engineering, and this dual nature of programming is part of its attraction.
Descriptions of the mathematical side are generally, in my view, too complicated. This article  presents a mathematical theory of programs and programming based on concepts taught in high school: elementary set theory. The concepts covered include:
- Programming languages.
- Kinds of programs: imperative, functional, object-oriented.
- Concurrency (small-step and large-step)
- Control structures (compound, if-then-else and Dijkstra-style conditional, loop).
- State, store and environment.
- Notational conventions for building specifications and programs incrementally.
- Loop invariants and variants.
One of the principal ideas is that a program is simply the description of a mathematical relation. The program text is a rendering of that relation. As a consequence, one may construct programming languages simply as notations to express certain kinds of mathematics. This approach is the reverse of the usual one, where the program text and its programming languages are the starting point and the center of attention: theoreticians develop techniques to relate them to mathematical concepts. It is more effective to start from the mathematics (“unparsing” rather than parsing).
All the results (74 properties expressed formally, a number of others in the text) are derived as theorems from rules of elementary set theory; there are no new axioms whatsoever.
The paper also has a short version , omitting proofs and many details.