My teaching and mentoring philosophy is primarily influenced by universal design for learning (UDL) principles [Rose et al. 2006]. The core idea behind UDL is that there is no “normal” student, and so focusing on teaching the “normal” student will ensure that no student has an optimal learning experience. Instead, developing a flexible learning environment ensures that all students can take the best path for their success. The UDL perspective draws heavily from work in disability studies and has obvious implications for learners who do not see themselves represented in a curriculum designed for “normal” students. In the subsequent sections, I describe how I have put UDL principles into practice while mentoring and teaching. I conclude with a description of the courses I am excited to teach.
I have mentored nine students across four universities in two countries. My students have won ACM student research competitions at POPL and PLDI, placed second at the ACM student research competition grand finals, won a SACNAS National Diversity in STEM presentation award, and gone on to rewarding careers in industry and academic programs at CMU, ETH, Princeton, and Stanford. In 2024, I was awarded a Demetri Angelakos Memorial Achievement Award (UC Berkeley EECS) and an Outstanding Graduate Student Peer Mentor Award (UC Berkeley) for “mentoring which went above and beyond the norm.” In line with UDL principles, my mentoring philosophy focuses on strategy development, building knowledge, and fostering interests and collaboration.
Strategy Development. I have had the privilege of working with incredibly ambitious and hard-working students. One of the most effective mentoring strategies, therefore, has been to help them set realistic goals, adjust these goals over time, and, when appropriate, intervene to put them back on track to achieve their goals. For example, I never tell students to participate in a student research competition. Instead, I like showing my students that these exist and, if they show interest, help them make realistic plans to participate. Part of this experience for students inevitably involves dealing with missed deadlines and other “failures.” In these cases, I attempt to strike a balance between helping them update their goals and supporting them through extra meetings, proof walkthroughs, or pair programming, as appropriate. Over time, my mentees become better at setting goals, planning for challenges, and monitoring their own progress.
Building Knowledge. Junior researchers often need help to engage with existing research. Academic papers use unfamiliar language and symbols, and the ideas within and relationships between papers can take a lot of work to decode. I have been able to mentor students effectively by helping them make explicit connections between research and material they have covered in courses. For example, I often ask students to read and present papers to me—often the same paper multiple times. During these presentations, I ask them to explain the relevant background material and related work. When students are missing background, I give them miniature lessons and, when necessary, encourage them to enroll in relevant classes. Over time, my mentees improve at drawing these connections themselves and become better at reading, understanding, and even communicating new research.
Fostering Interests. Students perform at their best when they are genuinely interested in their work and feel like a respected team member. I have been able to mentor students effectively by giving them a meaningful say in our projects. For example, I often ask students what they liked and disliked about the work since our last meeting, share what I am excited about, and then discuss how to optimize our plan moving forward. Sometimes, students are excited by a new concept they learned, and we can read more about it; sometimes, they are excited by a programming task, and we can budget more time for engineering. Even for projects with fixed goals, I have found that there is always a way to optimize the student’s learning experience. Over time, my mentees find topics they are excited about and develop a sense of ownership and pride in their work.
I have taught, either as a teaching assistant or guest lecturer, at the undergraduate and graduate levels for seven unique courses at three universities in two countries. These courses cover topics including programming languages, formal methods, software engineering, and artificial intelligence. Both my department and university have recognized my excellence in teaching. In 2022, I was awarded an Outstanding Graduate Student Instructor Award (UC Berkeley); in 2023, I was awarded the highly selective Outstanding Teaching Assistant Award (UC Berkeley EECS). I apply the same mentoring principles described above while teaching, but these are difficult to scale to large classes. Therefore, my teaching philosophy focuses on complementing my mentoring philosophy with autograders and inclusive course design.
Autograders. Autograders are an essential part of my teaching philosophy because they help increase instructor contact time by reducing the grading burden. I have helped develop three autograders, including the autograder used for all assignments in one version of UC Berkeley’s Introduction to Programming Languages and Compilers course (CS 164). Autograders are also interesting because they can enable flexible deadlines and immediate feedback to students. There is (mixed) evidence to suggest that these features can reduce stress, increase equity, and improve student learning outcomes [Cai et al. 2023; Hills and Peacock 2022]. I am actively searching for the best way to integrate these features into my courses, and I plan to periodically revisit the integration and relevant research throughout my teaching career.
Inclusive Course Design. While teaching programming languages and compilers for the second time, I built an audio interface to the course compiler and designed a section for students to implement their own. The implementation followed Schanzer et al. [2019], but the idea came from Kleege and Wallin [2015], who use audio descriptions as a pedagogical tool. Despite there being no theoretical reason for programming language interfaces to be text-based, all undergraduate compilers courses that I have encountered ignore alternate interfaces, like audio and graphical. Our audio interface highlights this fact, makes students think about the accessibility implications of their work, and serves as a useful motivating example for technical concepts like tree traversal and editing algorithms. The following semester, I participated in UC Berkeley’s “Preparing Future Faculty: Designing Courses through the Lens of Universal Design for Learning” and expanded the material to a full semester syllabus for a new introductory programming languages course. This new course uses my current understanding of research in education to make technical programming languages content accessible to as many students as possible. I am excited to put this new course into practice and refine my approach as I learn more about the relevant research and gain experience in the classroom.
I am ready to teach a broad range of formal methods, programming languages, and software engineering courses. At the undergraduate level, I am excited to teach Discrete Math, Programming Languages, Compilers and Interpreters, Software Testing and Verification, or related topics. I am also open to teaching introductory courses. At the graduate level, I am excited to teach Automated Reasoning, Formal Methods, Program Verification, Program Analysis, or related topics. I am also extremely interested in developing a graduate course on domain-specific automated reasoning. This course would combine ideas from programming language design and implementation with topics in applied logic, like automated theorem proving and satisfiability modulo theories.