Foundations of Programming Languages - Lee, Kent D. (Springer, 2017)
A career in computer science is a commitment to a lifetime of learning. You will not be taught every detail you will need in your career while you are a student. The goal of a computer science education is to give you the tools you need so you can teach yourself new languages, frameworks, and architectures as they come along. The creativity encouraged by a lifetime of learning makes computer science one of the most exciting fields today. There are engineering and theoretical aspects to the field of computer science. Theory often is a part of the development of new programming languages and tools to make programmers more productive. Computer programming is the process of building complex systems with those tools. Computer programmers are program engineers, and this process is sometimes called software engineering. No matter what kind of job you end up doing, understanding the tools of computer science, and specifically the programming languages you use, will help you become a better programmer. As programmers it is important that we be able to predict what our programs will do. Predicting what a program will do is easier if you understand the way the programming language works. Programs execute according to a computational model. A model may be implemented in many different ways depending on the targeted hardware architecture. While there are currently a number of popular hardware architectures, most can be categorized into one of two main areas: register-based central processing units and stack-based virtual machines. While these two types of architectures are different in some ways, they also share a number of characteristics when used as the target for programming languages. This text develops a stack-based virtual machine based on the Python virtual machine called JCoCo. Computer scientists differentiate programming languages based on three paradigms or ways of thinking about programming: object-oriented/imperative programming, functional programming, and logic programming. This text covers these three paradigms while using each of them in the implementation of a non-trivial programming language.