CS 345H: Programming Languages (Honors) Fall 2022

Lecture 0: Course introduction

Why are we here? Let's talk about JavaScript.

JavaScript has arrays:

[]
[1, 2, 3]
[1, 2, 3].length

What's [] + []? Empty array? Type error? No, it's empty string.

Ok, fine. JavaScript also has objects, also known as maps, also known as dictionaries:

{}
{a: 5, b: "hello"}
({a: 5, b: "hello"}).a

Can you add [] + {}? No, right, what would that even mean? JavaScript knows! It's "[object Object]" -- an object.

Of course, we learned in math class that + commutes, so {} + [] should be the same thing ... oh, it's 0.

Now for all the marbles, what's {} + {}? No arrays here! This is, of course, not a number! NaN.

(This was by far the most ridiculous one I could find, but let's not beat up on JavaScript any more and look at a couple of other examples.)

In Python, we can write lists and append them together:

a = [1, 2]
b = a
a = a + [3, 4]
a  # [1, 2, 3, 4]
b  # [1, 2]

Now, one of the little things we learn about many languages like C and Python is that instead of writing a = a + _ we can just write a += _. So let's try that:

a = [1, 2]
b = a
a += [3, 4]
a  # [1, 2, 3, 4]
b  # [1, 2, 3, 4]

That's a little weird. But Python's weird. Surely an industrial-strength language like C, the one we all trust, wouldn't do things like this?

uint64_t mul(uint16_t a, uint16_t b) {
    uint32_t c = a * b;
    return c;
}

What does mul(60000, 60000) evaluate to? Let's try gcc -o demo demo.c -O0:

3600000000

But -O0 is slow, we want to be fast. Let's try -O3:

18446744073014584320

Welp.

What's going on?

Programming languages are hard! And yet, programming is everywhere today—everything from critical services like medicine and aviation to less critical things like Instagram. What makes a programming language "good" for solving all these problems?

But these things are almost always in tension with each other.

Programming languages -- and this course -- are all about studying these trade-offs and how to make them better. How much of our cake can we find a way to eat?

How to study programming languages

One thing we could do: just study a few different programming languages.

What are some languages that people think are good, worthy of studying?

Of course, it's important to study negative examples too -- what are some languages people think are bad?

I have no idea which programming languages will be popular in the future. Some of my favorite languages are 70 years old, others weren't around 10 years ago.

We will do a little bit of studying particular languages to introduce you to some applications of the ideas in this class.

But mostly, this is a class about building foundations for programming languages. The whole course is really just about two things:

  1. What do programs mean?
  2. How can we be sure a program is correct?

But these two things carry a surprising amount of depth. We'll start with simple languages, and build them up by extending them with more features.

One thing we won't see much of in this class is answers to these two questions for "real" programming languages. Real languages are hard! Despite being well established, bringing the ideas of this class to real languages is still on the cutting edge of computer science research. We don't know how to do a lot of this stuff. Maybe you can be the one to figure it out! We'll see a few examples along the way of how people have tried to solve this problem, but mostly we'll concern ourselves with small example languages.

Nonetheless, these tools are incredibly valuable for learning new languages—the foundations haven't changed all that much over the years.

The ulterior motive of this course

In addition to learning the foundations of PL, I have a secret ulterior motive for this class.

Theory is hard and tedious. We're going to write a lot of proofs in this class. I don't like grading proofs. And I bet you don't like writing them all that much, either. Writing proofs on paper is hard because it's tricky to know if you really got it right.

So I also want to use this class to introduce you to a really cool family of programming languages tools called proof assistants. These are basically programming languages in which you write proofs and the computer checks them for you automatically. This has a huge upside -- the computer can tell you if the proof is correct or not! It also has a huge downside -- computers are really pedantic!

Proof assistants are really popular in PL research right now, but even beyond PL, anyone who works with math for a living can benefit from them. There's a growing group of mathematicians who use proof assistants to formalize their work, for example. We'll talk more about proof assistants in the next lecture, but the important point is: while I'll be writing some proofs on the board this semester, you won't be writing any proofs on paper for homework. All our proofs will be done in a proof assistant instead.

Course logistics

First thing to know is that this is actually two courses:

These are the same course, with only one difference we'll discuss in just a moment. For everything else -- lectures, homework, exam -- the course is identical.

Me, Sam, Sammy.

Prerequisites

Course website, Ed

Homework

Final exam

Paper readings

Course project

Grading

For 386L (graduate students):

For 345H (undergraduates):

For undergrads, the course project is redeemable against your final grade. That means that if you choose to do the project, we'll compute your final grade using both these grading scales and you'll get whichever grade is higher. In other words, trying the project can't make your grade worse. To choose to do the project, all you need to do is submit the proposal. You can't opt in after the proposal due date.

Please don't take this flexibility as an excuse to flake out on a group project, though. I reserve the right to deny you the redeemable option, or assign you a different project grade to the rest of your group, if this happens.

Other course policies

I prohibit the concealed carry of firearms in my office.

Academic integrity: