CSE 331: Topics
The course is organized into 10 topics, and we cover (roughly) one topic per week. Topics in the future are subject to change.
1. Intro to JavaScript
We start our journey to writing more complex, full-stack applications by learning a new programming language: JavaScript (JS). We will need JS to write code that runs in the browser (in Topic 2), but we can also use JS to write code that runs in the server.
We do not assume any prior JavaScript knowledge. We will cover all the parts we need in lecture. After learning the basics of the language, we will see how to write our own HTTP server in JS and then spend some time discussing how to debug the problems that we find in our code.
- Lecture:
- Section 1 materials:
- Section Slides (Section 1 Slides PDF or Section 1 Slides Webpage)
- Section Worksheet (Section 1 Worksheet PDF or Section 1 Worksheet Webpage)
- Section Worksheet Solution (Section 1 Worksheet SolutionPDF or Section 1 Worksheet SolutionWebpage)
- Section Code Solution (Section 1 Code SolutionCode Solution)
- Homework 0, due Thursday, June 26th, 11pm
- Homework 1 (HW1 PDF), due Thursday, July 3rd at 11 PM
- Change Log:
- Task 2: added detail that
listEvents
must be case-insensitive. - Task 3: added detail that
bookmarkSearch
must not allow duplicates. - Task 4: field in response for
listBookmarks
fixed to "bookmarks". - Task 4, 6: added instruction to uncomment lines in
index.js
to run parsing.
- Task 2: added detail that
- Change Log:
2. Intro to the Browser
In this topic, we switch to writing code that runs in the browser, presenting a User Interface (UI) that the user can interact with. We will discuss how UIs are written in modern web apps versus other settings and see how the code of modern web apps gets split up into manageable pieces.
- Lecture:
- Topic 2 Slides (PDF), Topic 2 Slides (PPTX)
- Slides 43-50 added after (6/30) lecture to show live "drawings" from class with text explanations matching what was said.
- Code:
- HTML example 1, HTML example 2
- Completed hello example demo, hello1-starter zip, hello1-completed zip
- Completed hello2 example demo, hello2-starter zip, hello2-completed zip
- Completed todo example demo, todo1-starter zip, todo1-completed zip
- todo2 example demo, todo2 zip, todo2-with-types zip
- todo2 is a version of the todo app with extra features (checkbox to complete items and button to delete items)
- hello3 example demo, hello3 zip
- hello3 is a version of the hello app with a dropdown (
select
element).
- hello3 is a version of the hello app with a dropdown (
- Topic 2 Slides (PDF), Topic 2 Slides (PPTX)
-
Section 2 materials:
- Section Worksheet (Section 2 Worksheet PDF or Section 2 Worksheet Webpage)
- Section Slides (Section 2 Slides PDF or Section 2 Slides Webpage)
- Section Worksheet Solution (Section 2 Worksheet SolutionPDF or Section 2 Worksheet SolutionWebpage)
- Section Code Solution (Section 2 Code SolutionCode Solution)
-
Homework 2 (HW2 PDF), due Thursday, July 10th at 11 PM
3. Client-Server Interaction
Having written already clients and servers separately, in this topic, we see how to connect them together into full stack applications. In this setting, the potential for difficult debugging is substantial. Bugs in the server can show up as failures in the client and vice versa, in both cases requiring us to debug across multiple programs to find the bug.
- Lecture:
- Section 3 materials:
- Section Worksheet (Section 3 Worksheet PDF or Section 3 Worksheet Webpage)
- Section Slides (Section 3 Slides PDF or Section 3 Slides Webpage)
- Section Worksheet Solution (Section 3 Worksheet Solutions PDF or Section 3 Worksheet Solutions Webpage)
- Section Code Solution (Section 3 Code SolutionCode Solution)
- Homework 3 (HW3 PDF), due Thursday, July 17th at 11 PM
- Change Log:
- Added clarification that two endpoints must be selected to invoke the save path callback.
- Added instruction to use the Gradescope assignment to debug in Tasks 4 and 5.
- Commented out fetch in App's
componentDidMount()
, added TODO to uncomment in Task 2. - 7/12: fixed unintended bugs in starter code, see Ed announcement.
- Change Log:
4. Specifications
Before we can talk in detail about correctness of our code, we need a definition of what the code should do. This is called a “specification”. It is important that our specifications are precise. In addition, we would like our tools for writing specifications to work for any language, not just TypeScript. For those two reasons, we will use our own mathematical notation that is independent of programming language. (And we will find additional uses for this notation in subsequent topics.)
- Lecture:
- Section 4 materials:
- Section Slides (Section 4 Slides PDF or Section 4 Slides Webpage)
- Section Worksheet(Section 4 Worksheet PDF or Section 4 Worksheet Webpage)
- Section Worksheet Solution (Section 4 Worksheet Solutions PDF or Section 4 Worksheet Solutions Webpage)
- Homework 4 (HW4 PDF or HW4 LaTeX Template), due Thursday, July 24th at 11 PM
5. Reasoning
Now that we have a better understanding of the work required to write and debug more realistic applications, we can see that being a productive programmer requires another tool, reasoning, which allows us to find the bugs missed by type checkers and unit tests. In this topic, we will see how we can reason formally and prove the correctness of code that does not involve any mutation. (Code with mutation is harder to reason about and will be examined in future topics.)
- Lecture:
- Topic 5 Slides (PDF), Topic 5 Slides (PPTX)
- Change log: Updated "Structural Induction ... Gone Wrong?" example to move x::nil case to inductive step (x::nil lists are created with recursive constructor, thus belong in inductive step not base case).
- Bonus lecture: Software Development Process Software Development Process Recording, Software Development Process Slides (PDF), Software Development Process Slides (PPTX)
- Topic 5 Slides (PDF), Topic 5 Slides (PPTX)
-
Section 5 materials:
- Section Slides (Section 5 Slides PDF or Section 5 Slides Webpage)
- Section Worksheet(Section 5 Worksheet PDF or Section 5 Worksheet Webpage)
- Section Worksheet Solution (Section 5 Worksheet Solutions PDF or Section 5 Worksheet Solutions Webpage)
-
Homework 5 (HW5 PDF or HW5 LaTeX Template), due Thursday, July 31st at 11 PM
6. Floyd Logic
In this topic, we continue our study of reasoning, now moving to slightly more complex (and more common) types of code. Previously we considered code without mutation, in which complex calculations are performed via recursion. Here, we will look at code that mutates local variables. In particular, this allows us to write loops instead of recursion. However, it also makes reasoning more complicated, necessitating new reasoning tools.
- Lecture:
- Section 6 materials:
- Section Slides (Section 6 Slides PDF or Section 6 Slides Webpage)
- Section Worksheet(Section 6 Worksheet PDF or Section 6 Worksheet Webpage)
- Section Worksheet Solution (Section 6 Worksheet Solutions PDF or Section 6 Worksheet Solutions Webpage)
- Homework 6 (HW6 PDF or HW6 LaTeX Template), due Thursday, August 7th at 11 PM
7. Abstraction
Now that we have learned our full set of tools for ensuring correctness, we turn our attention to the other properties of high quality code: understandability, changeability, and modularity. These properties are often provided by means of abstraction, which allows us to hide details of some parts of the code from other parts. This makes the code easier to understand and change, and allows multiple people to work on parts of the code simultaneously (modularity).
We will begin by studying how to hide the details of code via “procedural abstraction” and then see how to hide the details of data via “data abstraction”.
- Lecture:
8. Tail Recursion
In prior topics, we have seen problems that can be solved either with recursion or with a loop, showing that these two are sometimes alternatives to one another. In this topic, we clear up the relationship between them by showing that loops are equivalent to “tail recursion”, a special case of general recursion, and demonstrate how to translate between the two, allowing us to use whichever is more convenient for the current setting.
9. Arrays
In Topic 8, we looked at ADTs and saw that they describe the interfaces of many well-known data structures. However, the most commonly used data structure in imperative languages — arrays — was notably missing. In this topic, we rectify that omission.
As we will see, arrays create new reasoning difficulties that do not occur for alternatives like lists and basic trees. Their use of indexing gives us extra power but comes at a cost of more complex reasoning, requiring the use of “for any” facts to describe their known state. These are inherently more complex, but we can mitigate some of that complexity by turning to pictures as a simpler way of describing them.
10. Object-Oriented Programming
In our last topic of the quarter, we look at some difficulties that arise in object-oriented programming, especially when trying to create subtypes. We then look at solutions (in the form of design patterns) for working around some of the sharp corners of these languages.