COMP_SCI 111 - Fundamentals of Computer Programming I



This is an introductory course on the fundamentals of computer science. This class is meant to allow students to explore many of the core concepts of computer science (CS) and serves as the first course in core sequence at Northwestern. It is specifically designed to be open to students of all backgrounds and does not expect any computer science knowledge or prior programming experience.

This is not a software engineering course.

Please note that if you are looking to learn a specific programming language (i.e. “learn how to code in Python”), please consider registering for COMP_SCI 110 instead. While this course is certainly “an introduction to programming”, it is first and foremost an introduction to core CS concepts. We use programming as a means to understand and implement these concepts rather than simply learning a single programming language. The ideas we talk about in this class apply to all programming languages and set the basis for you to be able to quickly pick up new programming languages throughout your future studies in CS.

This course uses the Racket programming language, specifically two dialects designed to help students learn to program called the Intermediate Student Language with Lambda (ISL+) and the Advanced Student Language (ASL), and its associated Integrated Development Environment (IDE) DrRacket as its main programming tools.

The main goal in this course is to learn how to design and reason about programs.

The reasoning part matters because programs never work the first time. So you need to be able to figure what it’s really doing and why, then change it to do what you want. Programmers are first and foremost detectives and diagnosticians. We’re doctors trying to understand why our patients are sick.

The design part matters because the only way you’ll be able to reason about it is if you design it in a way that makes it easy for humans to understand, whether said human is your future self trying to add a new feature, or someone else who’s taken over the project and is now trying to understand your code.

Beyond this main goal, the course has a number of interwoven learning objectives. Students will work to understand:

  • Composition (literally “placing together”): algorithms and data are built up by joining simple components into more complex ones.
  • Abstraction: Complex arrangements can be reproduced and used as if they were simple components.
  • Metaprogramming: Programs can be used to aid the process of programming itself.
  • Programmability and universality: Computers are unique artifacts in that a single device can perform an infinite set of possible functions, including emulating other computers.
  • Programming as a psychological discipline: Programming is more about the limits of human intelligence than about memorizing bits of code.
  • Programming as an aesthetic discipline: Code can be beautiful; it can also be ugly. Those distinctions have real consequences in the world.

Programming is a powerful medium for creative expression. It can be a representational medium, a tool for thinking about problems, a way of amplifying and/or communicating ideas, a means of performing complex calculations over massive datasets, and more. Being a computer scientist is not a prerequisite for creating useful or advanced programs. In fact, most people who write computer programs are not computer scientists, but rather people who occupy a range of professions. Journalists, geographers, sociologists, scientists, artists, musicians, entrepreneurs, researchers, etc., use programming languages to accomplish diverse and specialized goals. And as data and computing increasingly influence and perfuse modern life, understanding the mechanisms (and risks!) that underlie these systems is a valuable modern literacy that is likely to serve you well.

Learning to program is not dissimilar to learning a new spoken/written language–first, you need to understand basic rules like grammar and syntax, then you need exemplar buildings blocks like adjectives, nouns, and prepositions, and only then can you use these ideas together to create computer programs. What this means is that you must dedicate enough time to practicing the basics in order to allow yourself to progressively move to more and more complex programming practice.

Taking this course means committing—for 11 weeks—to attending lectures, tutorials, and office hours, turning in assignments, practicing your programming skills, and most importantly, persevering when things get difficult. Asking questions throughout the class is not a sign of weakness. It shows that you are actively trying to understand what you know and what you do not know. We have an excellent staff of teaching assistants and peer mentors who are here to answer your questions, help you understand course material in different ways, and push you to your fullest learning potential. With your consistent and active participation in learning, you can navigate the material in the course and become a proficient programmer by the end of the quarter.