Basics | Goals and Outcomes | Requirements | Evaluation | Policies




Instructor: Eugene Wallingford

Course Resources

Course Readings

Course Goals and Outcomes


The study of programming languages and paradigms is fundamental to the discipline of computer science. As a computer scientist, regardless of your specialty, you should have a deep understanding of the principles of programming languages. They govern the design and use of every language that you will encounter. They affect the design of the applications you encounter. They even affect the architecture of the machines on which we run our programs. If you understand these design principles, then you will find it easier to be become an effective user of any language, to adapt to new paradigms as they evolve, and to design and implement new languages when necessary. You may be surprised to learn just how often you find yourself implementing small languages as a part of your applications.

This course aims to help you develop a deep, hands-on understanding of the essentials of programming languages. It does so by confronting you with the most fundamental idea in computer programming: The interpreter for any computer language is just another program. We will first lay the foundation for the analytic study of programming languages and then use those ideas to develop a sequence of increasingly detailed interpreters for a simple language.

In order to use this approach for the course, it is helpful that you learn a programming language that make it relatively easy to build language interpreters. We will learn Racket, a programming language that allows us to easily treat programs as data and vice versa. One of the extra benefits of learning Racket is that you will learn to program in a functional style, which will expand your programming repertoire. It will be the third "paradigm" in which you can program, in addition to procedural (Python, Ada, C) and object-oriented (Java, Python). Functional programming differs from the other two styles in a very important way: in functional programming, we compute only for values, rather than for side effects.

Note that this course is not about any particular programming language, nor even about a smorgasbord of different languages. We will not study the syntax of new programming languages so that you can use them to write programs. Instead, we will seek develop the knowledge and skills necessary for you to be able to study other languages on your own. The course does introduce you to Racket, a small and malleable programming language, as a tool for expressing the features of languages and writing language interpreters. It will be the microscope we use to study the broader principles of programming languages and paradigms.

Learning Outcomes

By the end of the semester, you should be able to:

  1. read and write programs in a functional style
  2. implement recursive programs over inductively-defined datatypes, in particular language grammars
  3. describe why and how to implement a language feature as a syntactic or data abstraction of a set of core features
  4. read and write interpreters for small programming languages

Course Requirements

Class sessions — Our class meetings will consist of a mixture of lecture, discussion, and in-class exercises. Much of our lecture and discussion material will go beyond what you read in our textbooks, so attendance is essential. I expect you to read assigned topics prior to the class session and to participate actively in class.

Homework assignments — Over the course of the term, you will complete ten to twelve homework assignments. These assignments will involve applying techniques learned in class and doing small experiments with programs that are provided to you. Some assignments will involve writing and some will consist of paper exercises, but most will involve programming.

Quizzes — During the term, you will complete three to four quizzes, one for each unit of the course. I call these "quizzes" because they last only thirty to forty minutes. The date of each quiz is tentatively set on the course home page. Ordinarily, I will announce any change to the schedule at least one week in advance.

Final exam — Finally, you will take a comprehensive exam at the end of the course. This may not be as imposing as it sounds, because you will be using the skills you learn throughout the semester.

Course Evaluation

You will earn your grade based on your performance on homework assignments, quizzes, and the final examination. I assign final grades using the following distribution:

Item Number Weight
Homework 10-12 30%
Quizzes 3-4 40%
Final exam 1 30%

Grades will be assigned using an absolute scale:

This means that there is no curve. However, I reserve the right to lower the individual grade boundaries at the end of the semester if I think that produces grades that better reflect what students have achieved.

Course Policies

Participation in the Course.   I try to accommodate student needs whenever possible, but I can only do so if I know about them. If you ever have to make alternate arrangements for a class session, an exam, or an assignment, please contact me, in advance, if at all possible. The safest way to make such arrangements is by notifying me via e-mail or phone of your circumstances and how you can be reached.

Office Hours.   My regularly-scheduled office hours are times when I am committed to provide assistance to you. No matter how busy I may appear when you arrive, the office hours are for you. You are encouraged to make use of that time. I am also available by appointment at other times if you cannot make an office hour.

Laptops in Class.   I encourage students to bring laptops to class and to use them as we write code and learn new ideas. In class, you should use a laptop almost exclusively for work related to the current session. Most importantly, your use of a laptop must never distract another student. This applies to other classroom technology, including cell phones.

Assignments.   All assignments are due at their assigned date and time. In order to receive partial credit, always submit your best effort at that time. I do not accept late work for grading without making a special arrangement in advance.

Collaboration.   I encourage you to work together on homework assignments, as a way to help you understand the problems better and to encounter different points of view. You must acknowledge any collaboration explicitly in the work you submit. However, any work you submit must be your own. Discuss ideas, but write your own answers, including all code. Undocumented or unacceptable collaboration is considered a form of academic dishonesty.

Use of Tools to Generate Code.   This is a course for learning how to write Racket code, functional programs, and language interpreters, not a course for learning how to use programs that generate code. Therefore, you may not use any AI tools to create code that you submit for this course. If you submit code that I think was generated by a tool, I will arrange to meet with you within a week to discuss your submission. If you cannot explain your code or use its technique to solve a different problem of my choosing, or if you do not meet with me within a week, the homework assignment will receive a grade of 0.

Academic Integrity.   UNI has an established policy of academic integrity. Plagiarism and other forms of academic dishonesty will not be tolerated in this course. See the UNI catalog under "Academic Ethics Policies" for details on the university's policy.

Required Syllabus Statements.   UNI has a number of university-level policies common to the syllabi of all course. This course will adhere to all of these policies.