Programming languages are the tools by which humans design new functionalities for computers. Modern languages emphasize a set of core features, which dictate the structure of programs and encourage particular styles of programming (so-called programming paradigms). This course studies important programming language features associated to functional programming, imperative programming, and declarative programming.

The course will illustrate these concepts in two ways: (1) through hands-on experience with cutting-edge programming languages, and (2) through mathematical models of programming languages. The first half of the course will use Haskell, and the second half of the course will use Rust. In parallel, the course will highlight the essence of programming language concepts by progressively developing a formal, mathematical model of a core programming language.

Students should have experience (or have taken a course) in at least one programming language. This will not be a purely programming course---the goal is to cover common ideas that occur across many languages, rather than to focus on a particular language. While hands-on programming experience is a major part of this course, there will also be more theoretical developments. Mathematical maturity, or a willingness to think abstractly about programming languages, will go a long way.