This course has the purpose of exposing students who have mastered advanced programming techniques and concepts to some of the foundational principles that underly the very programming languages they have been using. These same principles pervade many disciplines in and beyond Computer Science and can be found any time one needs to give and work with a representation of some domain. More specifically,
- You will see that a (good) programming language is not an ad-hoc collection of constructs, but a mathematical object whose external features (including expressiveness and usability) are the necessary manifestation of intrinsic properties. We will use judgments and derivations as a universal vehicle to talk and reason about language constructs.
- You will learn some of these general design principles, for example the use of types as an organizing principle, safety proofs as a measure of correctness, and the orthogonality of constructs, and study how they apply to the most common programming mechanisms, such as functions, records, variants and recursion, as well as to more specialized or esoteric concepts, such as polymorphism, exceptions, inheritance and concurrency. This will provide you with the tools to knowledgeably design your own language if the occasion arises.
- You will see that these same principles can be used to derive efficient and correct implementations techniques for a language. In particular, we will be able to establish correctness mathematically.
See also
Why Study Programming Languages?
This course will be coordinated with the edition currently offered on the main campus, taught by Professor Robert Harper. The material presented and the homeworks will be roughly the same.
This course is a gateway to the fascinating and multifaceted world of computational logic. If you find it enjoyable, you may also like 15-317 Constructive Logic (an investigation of logics that express algorithms or computations), 15-414 Bug Catching: Automated Program Verification and Testing (the use of a logical technique known as model-checking to verify complex systems), 15-417 HOT Compilation (implementation of compilers for higher-order typed languages) and 80-311 Computability and Incompleteness (a study of the logical foundations of Computer Science).
You must have completed
CS 15-212 (
Principles of Programming) or
CS 15-150 (
Principles of Functional Programming).
It is my goal to make this course successful, stimulating and enjoyable. If at any time you feel that the course is not meeting your expectations or you want to provide feedback on how the course is progressing for you, please
contact me. If you would like to provide anonymous comments, please use
the feedback form on the course home page or slide a note under my door. Comments of general interest will be answered on the
course discussion board.
The course has a programming component. Students are allowed to use any programming language they want to develop their assignment solutions. The only requirements are that the solution work as per the text of the assignment, be understandable to the instructors, and that the student be able to explain it. Said this, some programming languages will make the task simpler than others. In particular, using
Standard ML (SML) and similar languages, or
Twelf and similar languages, is likely to get you a working solution in a much shorter time than, say, Java, Python or C.
SML
A reference build of
Standard ML of New Jersey (SML/NJ), version 110.67, and Concurrent ML (CML) have been made available on the Unix clusters. To run it, you need to login into your Unix account. In Windows, you do this by firing PuTTy and specifying
unix.qatar.cmu.edu as the machine name. When the PuTTy window comes up, type
sml, do your work, and then hit CTRL-D when you are done.
You can edit your files directly under Unix (the easiest way is to run the X-Win32 utility from Windows and then run the Emacs editor from the PuTTy window by typing emacs — see also this tutorial). If you want to do all this from your own laptop, you first need to install X-Win32 from here. PuTTy is pre-installed in Windows.
If you want, you can install a personal copy of SML/NJ on your laptop. To do
this, download this file and follow these instructions. Personal copies are for your convenience: all SML programs will be evaluated on the reference environment on unix.qatar.cmu.edu. You need to make sure that your homework assignments work there before submitting them. To do so, you need to transfer your files onto unix.qatar.cmu.edu and test them there. You can do so by using the PSFTP utility which comes with PuTTy (or any of the many more user-friendly FTP front-ends).
Documentation
Useful documentation can be found on the SML/NJ web site. The following files will be particularly useful:
Twelf
A reference build of the
Twelf specification environment has also been made available on the Unix clusters and is accessed similarly to SML/NJ. The easiest way to use it is within the Emacs editor. Alternatively, you can install a personal copy on your laptop. Downloads, documentation and examples can be found on the
Twelf wiki (it supercedes the
Twelf web page).
Trying out Twelf or any other language is likely to get you bonus points
Latex
We strongly encourage you to typeset the written part of your homeworks in
LaTeX (we will take this into account as part of your
participation grade). It takes some getting used to it, especially if MS Word is all you've been exposed to, but it enormously simplifies producing pleasant mathematics. Here are some useful references:
This is a
12 unit course.
Tasks and Percentages
- Participation: 10%
- 6 homework assignments: 45%
- 2 weeks each
- Written and/or programming parts
- Handed out on Wednesdays
- Due on Wednesdays at 7:59am Doha time (6:59am after March 10)
- To encourage good work and integrity, the instructor may invite students to his office to explain their solutions. Should this happen, the students' explanations will become part of their grades for that homework
- No joint homework unless explicitly instructed
- Midterm exam: 20%, in class on 28 February, open books
- Final exam: 25%, 3 hours, open books
Evaluation Criteria
Your assignments and exams are evaluated on the basis of:
- Correctness: your arguments should make sense, your proofs should be valid, and your program should work in the reference environment
- Specification: say what you want to do before doing it. In the case of programs, use structured comments describing types, meaning of the returned value, invariants, and side-effects
- Elegance: written material should be of the same quality as what a professional would write. No typos, no bad grammar, clarity is paramount. See these notes about ML programming style
- Bonus points:
- 1% of the earned grade for each full day a homework is submitted ahead of the deadline
- up to 10% for particularly elegant solutions
- Negative points: no less than -100% if caught cheating
Because this course is coordinated with the
edition offered in Pittsburgh, the grades of individual homeworks and exams, as well as the final grade, will be uniformed to the performance of that class.
Late Policy
There are no late days. Assignments submitted past the deadline will get a grade of 0.
Academic Integrity
You are expected to comply with the
University Policy on Academic Integrity and Plagiarism.
Collaboration is regulated by the
whiteboard policy: you can bounce ideas about a homework with other students, but when it comes to typing it down for submission, you are on your own — no notes, files, snapshots, etc. Morever, you must wait at least 4 hours before writing down the solution.
Course Objectives
This course seeks to develop students who:
- demonstrate a high level of proficiency in the fundamentals of programming languages, namely
- are able to critically understand and analyze programming languages and their constructs
- are able to learn and apply programming languages quickly
- are able to analyze, compare, and choose the appropriate paradigm for a wide variety of computational tasks
- are able to approach or think about problems mathematically, are familiar with the mathematics that relate directly to the field of programming languages, and are able to master new mathematical concepts that arise in the context of their work
- master fundamental, advanced, and recent concepts in the field of programming languages
- think clearly about tangible problems and create innovative solutions relying on proven techniques such as abstraction, decomposition, iteration and recursion, inductive and deductive thinking, and know the limits of computation
- communicate orally and in writing in effective and appropriate ways within the discipline of programming languages, namely
- are able to understand and articulate technical ideas
- are able to follow and form cogent arguments
Learning Outcomes
Upon successful completion of this course, students will:
- know the basics of the theoretical foundations of programming languages and be able to evaluate languages, easily learn additional languages, and even design new languages. Namely, students will
- be able to extrapolate the concrete syntax of a particular language and assess constructs abstractly independently of the syntax they are written in
- be able to discuss the semantics of a construct and describe it semi-formally and formally
- appreciate the distinction between static and dynamic semantics
- be familiar with the standard assessment tools for programming languages, in particular type safety theorems, and be able to carry out a proof
- understand the main concepts in programming languages, namely:
- the difference between an interpreted and a compiled language
- the degree of abstraction at which a language sits
- the standard control flow mechanisms, including sequential execution, branching, loops, recursion and function invocation
- types as an organizing principle and an abstraction mechanism for data
- the most common mechanisms for code reuse including functions, modules and libraries
- have a clear understanding of the mechanisms underlying both imperative and non-imperative languages. Specifically, they will
- understand the standard and emerging constructs found in imperative programming languages such as conditionals, loops, functions, polymorphism, and exceptions
- understand the various principles underlying the object-oriented paradigm, including encapsulated objects, classes, and inheritance
- have familiarity with a functional language and functional programming concepts, in particular recursion, higher-order functions, continuations, and functional modules
- have had exposure to some of the paradigms for distributed and concurrent programming, with emphasis on the concepts of threads of computation, state change, synchronous and asynchronous communication
- understand basic logic and proof techniques necessary to create and understand a formal proof. Specifically, they will be able to
- apply formal methods of symbolic propositional and predicate logic
- describe the basic structure of and give examples of the following proof techniques: direct proof, proof by contrapositive, proof by contradiction, mathematical induction
- discuss which type of proof is best for a given problem
- relate the ideas of mathematical induction to recursion and recursively defined structures
- identify the differences between mathematical induction and structural induction and give examples of the appropriate use of each
- identify and correct flawed logic used in language design
- be able to communicate clearly and effectively ideas, concepts and intentions within the field of programming languages, namely
- be able to describe technical constructs (concepts) clearly, so as to be readily understood by their peers
- be able to give an individual presentation on a technical subject to audience of peers within the discipline of programming languages
- form a cogent, logical argument asserting and reiterating all technical concepts that lie within the bounds of the taught curriculum or their research within that curriculum