Teaching
I teach a variety of courses, largely focused on programming languages, compilers, and security.
CIS 400/600, Fall 2026 – Cybersecurity and Artificial Intelligence
My newest course examines how emerging AI systems reshape security in both directions: using AI for attacks and defenses, and securing AI systems themselves. The course progresses from classical foundations (reverse engineering, memory attacks) to contemporary topics including adversarial machine learning, prompt injection, jailbreaking, and agent escape.
CIS 531, Fall 2025 – Compiler Construction
An MS-level compiler design course covering the full pipeline from interpretation to x86 code generation: parsing, intermediate representations (SSA/ANF), control-flow analysis, register allocation, type systems, and optimization.
CIS 352 – Principles of Programming Languages
I am the lead instructor of CIS352, Principles of Programming Languages, which I teach every spring at Syracuse (it previously ran every fall and spring). The course is a project-focused introduction to the design, semantics, and implementation of modern higher-order programming languages. Course projects give students significant programming skills that involve building fragments of interpreters and compilers. The course uses the Racket programming language, and involves the implementation of Scheme-like languages; topics in other programming paradigms (object-oriented, imperative, or logic) are discussed upon occasion. Because our introductory sequence uses Haskell, CIS352’s initial focus is on untyped operational semantics, moving into concepts from type theory as the course progresses. Current course projects include network connectivity, ASCII-art rendering, Church encoding, metacircular interpreters, and type system implementation.
The Spring 2022 version of my course is available freely on YouTube, and currently includes 22 lectures between 10 and 35 minutes. I work to release several update videos from time to time (specifically to correct errata and refresh course content).
- CIS352 – Spring 2026
- CIS352 – Spring 2025
- CIS352 – Fall 2024
- CIS352 – Spring 2024
- CIS352 – Fall 2023
- CIS352 – Spring 2023
- CIS352 – Fall 2022
- CIS352 – Spring 2022
- CIS352 – Spring 2021
- CIS352 – Spring 2020
CIS 700, Fall 2024 – Modern Symbolic AI and Automated Reasoning
A second offering of my PhD-level seminar on automated reasoning, covering propositional logic and resolution, intuitionistic type theory and proof assistants, SAT/SMT solving, and Datalog and logic programming.
CIS 700, Fall 2023 – Formal Methods and Modern Symbolic AI
This PhD-level seminar is an in-depth exploration of modern research in automated reasoning, including SAT (DPLL, CDCL), SMT, first-order reasoning, intuitionistic type theory, model checking, equational reasoning, Datalog, ASP, and related paradigms.
CIS 700, Fall 2022 – Language-Based Security
This PhD-level seminar discusses relevant particulars of programming language semantics and logic. We then move to discussing topics such as hyperproperties, security type systems, and full abstraction.
CIS 700, Fall 2021 – Malware Analysis
This PhD seminar examines memory-safety vulnerabilities and defenses: shellcoding, return-oriented programming, symbolic execution, and abstract interpretation, with an emphasis on analysis methods for identifying malicious code behavior.
CIS 400, Fall 2021 – Introduction to Compiler Construction
An undergraduate compilers course: interpreters, closures and continuations, intermediate representations (A-normal form and continuation-passing style), assembly generation, and static analysis, culminating in a working compiler.
CIS 700, Fall 2020 – Formal Methods in Computer Security
This PhD seminar surveys the foundations of formal methods (logics, model checking, and related tools) and their application to reasoning about the security of computational systems, combining foundational material with research-paper discussions and programming projects.
CIS 700, Fall 2019 – Program Analysis: Foundations and Applications
This PhD seminar course focuses on the theory and practice of static analysis. We first cover standard formulations of programming language semantics (e.g., metacircular interpreters, big/small-step semantics) and continue by introducing ideas from lattice theory, abstract interpretation, and abstract-machine-based analysis techniques.
Before Syracuse
CMSC 245, Spring 2019
This is the second iteration of my programming languages course at Haverford.
CMSC 395, Fall 2018
CS 395 is a project-based course that teaches software engineering by pairing student groups with nonprofit groups for which they build apps. I was really proud of the course outcomes, and we were able to work with some really awesome organizations.
CMSC 107, Fall 2018

Fall 2018 I taught a revamped version of the introductory course at Haverford. My offering was fairly unique in that I replaced all of the course projects with incremental assignments that had students write core data structures and eventually built up to the implementation a tile-based videogame (complete with enemy AI!). A few example projects are available here, here, and here.
CMSC 311, Spring 2018
Spring 2018 I taught a new course in computer security. We covered a broad set of attacks and defenses. Students work end-to-end course projects, and hold each other accountable by finding exploits and breaking each other’s projects.
CMSC 245, Fall 2017
The course covers programming paradigms at several different levels of hardware abstraction, and teaches students to both understand how the machine executes code and its core abstractions for representing data. The main course website is here.
CMSC 330, Summer 2015

Link to GitHub repository with examples
As a PhD student in programming languages during the summer of 2015, I taught CMSC 330, an undergraduate course in PL at Maryland. CMSC 330 covers a wide range of concepts in programming languages: both foundational and practical. In particular, the students learn OCaml, Ruby, and Prolog, and learn core material such as automata theory (finite state machines and grammars) and programming language semantics.
For the Summer 2015 iteration of the course, I reworked a large part of the lectures to cover the same set of material, but presented it in an interactive style: developing concepts in class, while supplementing this development with projects and course notes. I also elected to put more emphasis on teaching functional programming and programming language semantics. The course included extensive coverage of small step semantics: for one project students implement an interpreter for a core-ML.
Relevant lecture material I particularly enjoyed writing includes: