Programming Languages: Principles and Paradigms