Computation occurs over a variety of substrates including silicon, neurons, DNA, the stock market, bee colonies, and many others. In this course we study the fundamental capabilities and limitations of computation, including the phenomenon of universality and the duality of code and data. We touch upon the following questions: Are there functions that cannot be computed? Are there true mathematical statements that can't be proven? Are there encryption schemes that can't be broken? Is randomness ever useful for computing? Can we use the quirks of quantum mechanics to speed up computation?