It looks like you're new here. If you want to get involved, click one of these buttons!
By Craig Dietrich
Courses in Critical Code Studies (CCS) range from code classes with critical theory mixed in, to literary classes with code mixed in, to, more recently, classes where CCS is taught from start-to-finish, not to mention CCS “in the wild” where code critiques find their way into the hands of many inside and outside of teaching environments. With such a breadth of activity, certain growing pains can emerge, which is why we’re fortunate to have Mark Marino’s book, Critical Code Studies, to act as a guide and, in some cases, a lesson plan. The book includes an introduction to the field and also the Critical Code Studies Manifesto, a further explanation of the relationship between code and culture. Beyond the book, there are numerous other texts that can help with teaching, from articles in the Digital Humanities Quarterly to other books such as 10 PRINT CHR$(205.5+RND(1)); : GOTO 10. All of these include the required CCS components: code and critical analysis.
On its own, code can be tricky to teach. Code doesn’t always print well onto a page, it is difficult to read code up on a projector screen, and code is often dependent on other code and libraries that make it difficult to work with some code snippets. With such challenges, and those were only to name a few, code can be difficult to present in a classroom. Other questions related to teaching code include: in what format is code assigned? How is code annotated and using what tools? How are group discussions led when students come together? And, can students see code run? Questions like these are common in any field, like CCS, but are rooted in pedagogy that for most of teaching history placed the written word on paper as the primary means of knowledge transfer. Now that code is not an abstract concept for many, teaching must now cope with the nuances of code and requisite pedagogical changes.
Critical analysis in the classroom seems like a given: teachers are constantly asking students to think critically. Though, CCS asks readers to think along the lines of Critical Theory and Cultural Studies, sets of knowledge with specific vernaculars. How do we expect a student to learn the nuances of code—such as programming languages, algorithms, and data structures–while at the same time learning critical approaches to knowledge? The two can seem incompatible until some initial CCS examples are offered up. Consider the Transborder Immigrant Tool, a program for turning cell phones into devices that find water in the desert that is featured prominently in Critical Code Studies. When code is amply annotated with comments that point towards an activist strategy, as it is with the Tool, it is easier to imagine how it could operate successfully for both critical analysis and code lessons. But what about code that isn’t constructed in such a way? How can the interest of students be maintained across literary, computer science, and other fields when the criticality of code is more opaque?
Whether CCS is sprinkled into a literary or computer science class, constructed from the ground up as a semester-long endeavor, or something in between, there are few public syllabus examples that can be called upon during the formation of a course. However, that can change in this working group thread. For example, here are the assigned books for a syllabus I am creating for a full-length CCS class:
- Paul du Gay, et al, Doing Cultural Studies: The Story of the Sony Walkman (First Edition). Thousand Oaks, CA: SAGE Publications (1997).
- Mark Marino, Critical Code Studies. Cambridge, MA: MIT Press (2020).
- Nick Montfort, et al, 10 PRINT CHR$(205.5+RND(1)); : GOTO 10, Cambridge, MA: MIT Press (2012).
- micha cárdenas, Poetic Operations: Trans of Color Art in Digital Media. Durham, NC: Duke University Press (2020)
The inclusion of Doing Cultural Studies points towards the need to introduce students, in the context of this course, to the generalities of Critical Theory. The next two books are likely to show up on many CCS syllabi, while the last, Poetic Operations, suggests that code for computer operations isn’t the only code that CCS can analyze. In this case, the books are purposefully targeted at both computer science and non-computer science students.
It may also be important for a syllabus to introduce Critical Code Studies as a field; is a knowledge of CCS assumed or should it be described at the onset of the course? While my personal taste is to let definitions develop organically as a course develops, my CCS syllabus includes an introduction by way of quoting Critical Code Studies and other texts. For example:
“To read and interpret code does not necessarily mean to discover secret content or to uncover its unconscious bias or even to reveal unusual functioning. Instead, to read code critically is to explore the significance of the specific symbolic structures of the code and their effects over time if and when they are executed (after being compiled, if necessary), within the cultural moment of their development and deployment.” (Marino 23)
Here it is put forth that CCS isn’t necessarily the search for “gotcha” code, something that might come as a surprise (or bummer) to students new to CCS. In fact, as Critical Code Studies points out, CCS can be used to disprove so-called Climategate code, a sort of “reverse gotcha”, so code critiques of this rhetorical form do exist. It is up to teachers to find a balance between code intertwined in activist concerns and code that does, say, everyday tasks. Or to put into CCS terms: it is up to teachers to convey that the meaning of code changes when placed in activist, reactionist, and functional contexts.
For this Working Group thread, I propose that we post syllabi for courses that may include or focus on CCS, and syllabus components such as individual assignments and descriptions. Submitted content need not be for courses actually taught, but can include prospective materials. Discussion can jump off from the questions posed above, or new questions can be posed. But let’s not forget important ancillary discussions, such as: the kind of CCS courses that are being approved at colleges and universities; CCS-adjacent methodologies; classroom environments that promote the reading of code; field trips to code/art shows; and, institutional support for CCS. Of course, code snippets and critiques can only benefit the conversation, so feel free to post away!
Discussion questions gleaned from the text above:
Comments
I often find myself wearing multiple hats and speaking from different roles as it comes to critical code studies and software pedagogy. For the last several years, I have taught full-time in the classroom and the courses assigned to me have been focused on web development and game design. As it comes to teaching programming, I've had to adopt a more practical, "here is how it works," approach than the critical one I might want to use as it comes to software. When dealing with sometimes 80+ students in a single class learning the game engine Unreal, for example, thoughtful critique and engagement is simply not always possible. (That written, Unreal's "healing is negative damage taken" is very telling about how it sees players interacting with virtual worlds.)
I'd like to engage with these questions from two perspectives. For the first, I'll answer on how I've taught code and then from how I would have preferred, and would like, should I ever get the chance to focus on critical code studies approach.
Presentation
1. In what format is code assigned?
(A) I usually assign code in a scaffolded approach with focus on portfolio pieces. For example, in a class on full-stack web development, we would start with a simple client, next build a simple server, and then work on having them communicate. Each piece could be by itself and so too could the entire, working thing.
The formatting of the assignment or class is based on the topic and curriculum connection. In an introduction to programming courses designed for graduate students, I might ask for a written response to some code. Something like "How do you think it works? What concepts does it seem to use and why?" For a course designed for level design students, it might be a whiteboxed layout. This can vary widely.
(B) I would love to assign specific, existing code as part of a reading list and then work through the code line-by-line as part of a discussion, adding in new comments as the class comes to understand parts, creating our own "version" of the code with notes added by the class.
2. How is code annotated and using what tools?
(A) I have annotated code in two ways. First, in the LMS, I include code snippets with comments or screenshots with highlighted sections. Next, either in-person or via video go over examples of the same code, often starting with bare or limited code and then adding in concepts to build back up in complexity.
(B) As mentioned in the last question, I'd love use something like GitHub's Pull Request conversation feature where students could leave comments and have conversations about a version of code where others could see and then make merged changes. (If someone knows of a system like that, please let me know!)
3. How are group discussions led when students come together?
(A) For design courses with smaller numbers of students, I've asked them to consider an issue or re-design something according to a particular principle or concept. This is much, much harder for large classrooms of programming students.
(B) Depends on the class, level, and expectations. (That's a cop-out, sure, but it really does!)
4. And, can students see code run?
(A) I used to use Replit's hosting for hosting example. Students could see, edit, and run it all from a web browser. However, the pricing structure has changed and that's no longer as useful as it once was. I have also used jsFiddle. Anything with a web browser for teaching code, like Twine, Bitsy, or even P5.js, is strongly preferred to always show running code whenever possible.
(B) Visual Studio Code's online editor is quote good and I'd love to use it more in a classroom setting to teach.
Criticality
1. How can students learn the nuances of code—such as programming languages, algorithms, and data structures–while at the same time learning critical approaches to knowledge?
I think this starts with a powerful but often overlooked premise. All interfaces mediate. By dealing with a language, even a spoken one, we are engaging with an extended history of concepts, embedded biases, and assumptions about the world as congealed into a linguistical practice based off the culture of the majority of its users. The same is also true of programming languages. They are built on application programming interfaces. Many of them. Each mediating access between other, often hidden or restricted systems. As I told someone recently, "programming languages aren't found out in the wild; they are made and changed by their communities."
If we begin with the premise that digital languages are created to solve specific sets of problems, we can address them as cultural artifacts. Why was it created? What is it trying to solve, and how? What biases might it have encoded within it?
Digital computers are machines running within finite resources. Each and every data structure was created to solve a problem at a cost. Time and accuracy is always traded. With that in mind, examining why, for example, object-oriented programming is a dominant paradigm and process-oriented programming is not can help to apply a critical lens to understanding code. Why was this data structure used? Why not another? Was the developer using a comfortable structure or a more efficient one? Why?
I wish I held the answer for the exact threshold of knowledge to be able to critically engage with code. Is it enough to teach major structures? Do we have to teach multiple languages? Data structures? Bubble sort? This question plagues so many of us.
2. How can the interest of students be maintained across literary and other fields when code is difficult to decipher?
What's the pedagogical goal? Are we making programmers or improving digital literacy? A problem I know I can get myself into is wanting to explain all the details of some digital system rather than just the knowledge needed to use it.
I like to put it to people this way. Does knowledge of French help you to use the theories of Foucault? Oh, sure, being able to read the original texts can give a richer understanding, but that's a deep labor cost for many. Instead, we can look at the "output" and "translations" of the concepts and use them to make our own work. Is it enough that people know what a function is, or should they know before 1956 the word "function" was not applied to programming and the word "subroutine" was used instead dating back to at least 1947 in published academic writing? I know, at least speaking only for myself, I worry I know too much and it becomes harder to explain concepts without wanting to expand on all the connected topics.
Thanks for this discussion. I'm really interested in ways to incorporate CCS into courses that I have "already on the books" within New Media, which typically include intro-level "Programming for visual artists" type courses (using p5.js or Processing) and upper level studio courses. We do have broader introductory survey courses, though these do not expect students to have any background in code previously, and include roughly equal amounts of students that have taken our intro Programming for Visual Artists course and those that haven't. So that said, I often can't assume students have a particular background or knowledge coming in, and I'd love to hear how other educators are dealing with this on the undergrad level.
Often, when I teach CCS-adjacent material in my classes I use the aforementioned 10Print book as well as Taper online literary magazine https://taper.badquar.to/ due to the work being presented online and always with the ability to "view source" and because there are variety of projects available for students to view.
When possible, and because I'm based in a major metropolitan area, I have led student classroom trips to visit code-art related exhibits and conferences. This has been particularly effective for getting students more deeply engaged and seeing how the work engages with the rest of the world outside their classroom.
At an institutional level there is often support to expand technology use and training, but not really a built-in engagement with CCS. I'd love to hear how other educators have found or cultivated institutional support.
I like to teach CCS in my digital literature courses as part and parcel of how we read, analyze, and interpret works of digital literature, especially when they’re open source works. I like to assign the first chapter of Mark Marino’s Critical Code Studies book.
Here’s a link to that unit in the course, which is foundational to all the activities in the semester: https://leonardoflores.net/2360/2024/01/22/weeks-2-3-generative-writing-2/
To close out the first unit in my course, I assign a Creative Code Studies activity, in which they modify a generative work to achieve their own creative goals or create their own textual engine. Here’s a link to the assignment: https://leonardoflores.net/2360/2023/09/06/creative-project-1-generative-writing/
So through creative coding exercises, I invite reflection on code.
Thanks @craigdietrich for this terrific topic. I will share my syllabus in a bit, but first I wanted to jump in and pursue your questions, namely, how much programming should be taught in an interdisciplinary CCS course and with what books?
When I taught a CCS course this past fall, I had students of every level, from first-year to PhD candidates, with pretty much the full range of programming experience. (Here's the schedule of readings.) My fabulous students from that class are assisting the Working Group this year. I wanted to introduce at least some basic programming concepts, so I turned to Aesthetic Programming by Winnie Soon and Geoff Cox. While I love the way that book shows how to spin out a concept, like looping, into large associations, that book announces that it is not designed for novices. A colleague recommended that an easier introduction is Getting Started with P5.js by McCarthy, Reas, and Fry, which I may use next time. A grad student in the past started with Shiffman's The Nature of Programming, but that's fairly sophisticated, and the student already had quite a bit of experience with code. There's Nick Montfort's introduction to Python in Exploratory Programming, which has a great nonprogrammer's orientation and some fun exercises. I also wonder if a book like Once Upon an Algorithm would work.
It goes back to your question about how much familiarity a student needs with programming to be able to do the work of CCS. With LLM-assisted readings, more code is becoming accessible, but that goes a bit beyond reading a work in translation. It's reading a work as machine-translated and interpreted.
I walked away from the semester with a new appreciation for the art of teaching programming, which had already begun with courses I had taken. CCS is definitely a big ask. And asking professors to teach programming and teach critical theory and THEN teach the application of the one to the other, is quite a big ask.
What thoughts and experiences have people had?
In Winter 2023 I taught an upper-division undergraduate course at UCSB called English 149: Media and Information Culture: “Decoding Digital Literature: Critical Code Studies.” It was for non-programmer humanities majors with no technical prerequisites with the goal of making CCS the main course topic rather than a unit in a larger course.
This was the sequence of main readings through the quarter:
Some of these works I chose because I was very familiar with them, others were late additions based on recommendations (in particular Mark recommended Croll, which was a hit). Other works that I considered but did not include this time around included Reading Machines: Toward an Algorithmic Criticism, Poetic Operations, Videogames for Humans, and Oram and Wilson's Beautiful Code.
My main approach was to present a series of scenarios in which code might be studied as problems, then present critical writing as modeling strategies in response to those problems. Hence beginning 10 PRINT by introducing the single line and immediately introducing the need to run an emulator to execute the code (and play with it), and from there the limitations regarding e.g. the Commodore keyboard mappings and the idea that code is written and runs in a platform context. ELC Volume 1 presented a range of often"broken" works that are not that old, and students struggling with both Java web applets and Flash plugins (via Ruffle) set the stage for more issues in ephemerality, archiving and preservation that accompany working with most code objects.
The course also surveyed a lot of material by using break-out groups to let groups of students choose individual cases and drill down into them. For example, the class read and discussed Critical Code Studies chapters 1 and 2 together, but then broke out into groups to study only one of the following four chapters separately as case studies:
...and then reconvened to report back to each other the cases and discuss chapters 7 & 8 jointly.
The midterm was to choose a digital work from the course and develop a short critical discussion of it based on a “remix”--most students chose either 10 PRINT or Taroko Gorge, with about half writing about a critical discussion of an existing 10 PRINT "variation" or Taroko Gorge "remix", while the other half choose to create their own original variation / remix and then explain it in the context of the original.
Reading Project came next -- "Project for Tachistoscope" is a bigger object with more moving parts AND it depends at least in part on understanding the Flash IDE, expanding the idea of a platform / stack from the execution side to the authoring side as well. For simplicity and accessibility I demonstrated decompiling Tachistoscope with FFDEC rather than setting up an emulated Flash authoring environment and made the assets available to the class for browsing. Practical demos in decompiling Java applets and Flash (and reading the HTML+Javascript of Taroko Gorge) also modeled some additional approaches for working with the more contemporary ELC Volume 4, which we turned to next. Students did an in-class exercise browsing the ~130 works in the collection:
...and then signed up for multiple works of interest before again consolidating the 20 or so top suggestions into a few reading groups around selected case studies based on their interests--in this case:
The course final, to "Study a Digital Literary Work" had a group or independent option:
Most students chose to focus on a work from ELO v4, but some chose to another work from the course, or proposed their own outside work, including "a digital literary video game, e.g. from Steam, GOG, Itch.io, et cetera (this should be accessible enough that the code may be examined, although it need not be fully open-source)."
The course had some real successes and some failures -- it was ambitious and took many risks, and I feel that some things worked and others failed. When I offer it again I will probably slow things down, streamline the materials, and focus on a smaller number of shared objects. Still, I think that the breakout and choose-your-own-code structure was productive, just a lot of work to support. Notably I did not choose a primary programming language for the course, nor attempt to teach the students BASIC, HTML, Java, Javascript, or Python et cetera in a systematic or sustained way. If the goal had been for students to engage with a single language and build literacy within it (as an intro to CS curriculum) then I would have selected all the materials backwards from within the constraints of that chosen instructional language. Instead I threw us into the deep end with the assumption that every new code example would be a new foreign language (with all the limitations and opportunities that experience entailed). I'm still reflecting on whether there could be say a 5-week version of that experience that paired with a 5-week intensive focused only around, say, HTML+Javascript.
Appreciate the discussion so far! I'm one of @markcmarino 's students from last semester, and I would love to share some of my thoughts on what I believe the course accomplished and what I think could have expanded more. I hope that my comments and thoughts can expand the discourse on teaching critical code studies!
CCS is all about the networks of people that write, read, and use code. The incredible potential in CCS is that not only does it base itself upon existing explored fields that examine the effects of software and the power in software, it also digs a level deeper into examining the actual code which software is being constructed from. It strikes deep into the core of the problem: code bears power. Code, when compiled, when deployed, when executed, create tangible effects that have real consequences. They control myriad objects in our lives and society that make decisions and do acts. Yet code is not a monolith -- during its construction it is being read and written by many people, with varying levels of expertise. Software is conceptualized as its gross effects but constructed through individual lines of code. Therefore, arises CCS, bringing the humming piece of code right under our noses into view, and asking the question of "How can we read this?"
Yet another question immediate arises. Who are we to read code, and what code do we read?
Code is polarized in the dimension of transparency. Corporate code is incredibly opaque to the point that even former engineers sign away their rights to their own code and NDAs that gag them from leaking any crumb of the codebase. Conversely, open source code is capable of being seen and downloaded by anyone who has an internet connection and the community literally preaches the nobility in contributing to open source. If we desire to examine the corporate working code underlying software and services billions of people depend on, how do we obtain access to it? If we desire to examine open source code, how do we sift through millions of inconsequential toy-codes that distracts us from impactful ones?
On the other hand, who CCS appeals to is also polarized. Does CCS serve as a tool for examining code in order understand society and culture? Or does CCS serve as a guideline to apply to coding and used when developing code? Or does CCS serve as a conceptual understanding of what code can be beyond functional? The nascency of the field and scarce application in humanities scholarship reveals that examining code to understand society and systems of power is still something that needs to be formalized and systematized. Moreover the field of computer science and the tech industry rarely develops software and innovation which abides to specific guidelines of ethics, justice, or transparency. The discourse and horrifying revelation of the problems of AI -- in its threats to privacy, fairness, justice, human rights, to even democracy at large -- is just a window which revealed the deep-seated history of problematic histories in code development, code distribution, data collection, and computer science innovation. In the end, we ought ask, who is CCS for, and how should they apply CCS?
Therefore, as CCS scholars and educators, there is a necessity in critically approaching our own practice to consider the purpose and audience of CCS itself. That is the idea that I want to append to the list of questions we are holding in attention as we approach the topic of teaching CCS.
I intend to write a longer response later, but for the moment I want to point out some practical limitations which I feel like this field would encounter in a classroom setting, motivated by the arguments I made above.
CCS needs to have a broad range of code to examine. Code that is art and code that is commercialized must go hand in hand when applying CCS. CCS must examine short pieces of code and fragmented functions while also examining whole codebases and complete systems. CCS's tools must be robust to such disparate forms of code to be meaningful.
CCS needs to address the diverse concerns of the audience learning it. How can a humanities student integrate CCS as a text reading methodology and use it as supporting evidence to a broader thesis? How can a computer science student integrate CCS as a theory to integrate when developing novel architectures and writing code? How can an art student integrate CCS to use code as a route to critique, represent, and examine the world?
These goals are ambitious, but they are necessary, because engaging with code is the inevitable future to understand our software driven, techno-centric society. And CCS can be the crucial theory central to it. The only question is from what it is now to what is possible, how do we bridge the gap effectively?
I'd like to unite @markcmarino's question of "...with what books?" with the later part of @eleazhong 's reply on the need examining code "that is art and code that is commercialized must go hand in hand when applying CCS." As part of this discussion, and a common observation I've had as an "opposite" member of teaching CCS -- most people, it seems, come to CCS from humanities whereas I started in computer science and ended up in digital humanities --, we all tend to focus on code that is more art than commercial projects. This is a natural result of many of us here teaching writing, visual arts, or communication courses. (I have a MA in Rhetoric and Composition! I understand!)
I've been wondering, though. Do any of you teach commercial code? Or large codebases? One of the insights from my dissertation and its application of CCS was a lack of research on large code libraries and ecosystems. Much of this is simply a matter of scale. Taking on tens-of-thousands of lines of code is a significant ask. It's far easier to do a close reading of one file than, say, 60,000+ lines of code in a large code library. (Distant reading approaches help with this! And so too does static analysis tools!)
To those with greater pedagogical agency than I've had, would you be willing to take on something like A Commentary on the UNIX Operating System (1976) where an extended part of a semester was dedicated to taking on and annotating a single, large codebase as a class?
Would you assign something like the Zork I (1980) source code or the Player class from Celeste (2018)?
@dancox -- Great question about large code bases. Briefly, I haven't taught industrial code, but I have taught long(er) code bases. I haven't done a long sustained annotation in the classroom, only in projects and this working group (e.g. during the CCSWG 2018 on Gender and Programming Culture when @JudyMalloy coordinated a shared look at COLOSSUS and LUMINARY: The Apollo 11 Guidance Computer (AGC) Code).
In the classroom I have experienced teaching the Zork I / Adventure source code in a unit pioneered by @Ryan_Leach during a course that we taught together. He may be able to comment more on the specifics of the design and its pedagogical goals, but I will note that text adventures do some parsing based on token matching so readers can begin with the inputs/outputs on the screen and often are able to use Control-F Find to jump to relevant code based only on the play transcript. In interactive fiction (IF) playing and then searching specific aspects of that play against a large code base that generated it is (sometimes) fairly easy, even with code on the order of 1000s or 10,000s of lines. This wouldn't help a student trace e.g. the main control loop of an IF parser, but does help answering the question "which rule(s) produced this response?"
In that vein, @Ryan_Leach and I also collaborated on teaching larger Emily Short works in Inform 7 such as Bronze. That story.ni file is 3461 lines long, but Inform 7 is verbose and doesn't use line wrapping -- some lines are more than 600 characters long, so the the work is probably closer to the equivalent of ~10,000 lines in another 80-char wrapped code language--and because Inform 7 is NLP, some of those long lines are not strings, they are code-paragraphs with mixed rules, strings, and string templates that compile. For example, here is line 364:
...but our forum assumes 80-char wrapping of
<code>
, so it is easier to see that one line formatted as a<blockquote>
. Here is line 364 again:Again, this is not an industrial code-base, but ~50,000 'words' is large enough that "just read the whole code first" is quite a heavy lift for students... and search-based ways into exploring and teaching the code might be appropriate, especially in a shorter unit.
Both text adventure examples (zcode and Inform 7) are still probably(?) much easier than your example of Celeste, where an observed event on screen with e.g. an explody-animation might be a call to
SlashFx.Burst()
but there isn't an obvious way to jump to the mapping in the code without a lot of scrolling around in a very long source (unless you were say debugging through an emulator or using other live inspection tools). My teaching with Ryan was before our LLM watershed moment so our paradigm for small code bases was "read" and for large code bases was "browse" + "token search". I would be interested to see how LLM-assisted code search of Celeste might perform with an LLM prompt such as:In that spirit of non-textual examples where it is difficult to map the interface to the code I will also mention one last example, a more recent challenge in my 2023 critical code studies class, which involved my distributing a decompile of Poundstone's Tachistoscope.swf Flash file to the students as a downloadable zip. The FFDEC decompile contains 1642 different files in dozens of nested directories -- 49 of which are .as ActionScript files and 59 of which are .txt assets (if you can find them, with many more being image files, sound files, et cetera). The total number of lines of code is actually quite small, with many of those files only containing ~4 lines of ActionScript and the total lines being in the low hundreds, yet the code base is "large" in the sense that clicking around in the unzipped folders is as much or more work than navigating one 5,000-10,000 source file, and the students still need to develop techniques to make the source legible before they can get to questions of functionality and meaning.
@jeremydouglass Fascinating! Yes, I'd be very interested in any comments or notes from teaching the Zork I / Adventure source code and the role of Control-F searching through files to help students understand the input, output, and rules of parser IF. I tried my hand at a workshop on Zork I (1980) a few weeks ago . It seemed to go well for moving from the input to code side, performing those searches for strings, but much less well on trying to understand how the code worked. I only had an hour and would like to revisit it as a longer module exploring the code and re-design the on-boarding process better to help students understand what the object data structure is and how it works in ZIL.
Here is where I admit the Player class from Celeste (2018) pull was a bit of a trap. I was interested to see how other people might react to its complexity and sheer number of lines for a single "class." It is incredibly complex and not something I would necessarily assign to those coming to CCS for the first time. I examined it with students as part of a game development class focused on 2D games. It showcases something called "coyote time" present in many platformer video games. (This is a great explanation of it I've also shared with students.)
When viewed in a frame-by-frame analysis, characters in games like Celeste (2018) seem to float in the air when moving off platforms. This is because there is certain number of frames before gravity is applied, creating an effect of allowing the character to act like the Coyote from Wile E. Coyote and the Road Runner while the cartoon character freezes in the air after running off a cliff and only falls when he realizes there is no ground beneath him. Because of this implementation in Celeste (2018), it is possible for the player to perform very complex movement mechanics when taking advantage of the milliseconds in which the character floats. This has been extended into a set of levels designed to abuse this mechanic into even harder levels. (About a month ago, there was a speedrun of a modded version of the game where most levels are completed in around a minute.)
On a very different note, I have been playing around with potentially teaching programming as a "peer programmer" activity with GitHub Copilot where comments are used as a prompts to create simple code structures.
For example, I might ask a student to write their own code in JavaScript:
Next, I would ask them to chat with GitHub Copilot using the same prompts, accepting the first response.
Finally, I'd ask them to discuss if the code they wrote is different than that suggested by Copilot and why they might think it would suggest something different.
This may be a bit spicy, but why not?![:) :)](https://wg.criticalcodestudies.com/resources/emoji/smile.png)
One difficulty here is that in my experience, institutions aren't particularly good at teaching how to code in the first place, let alone things like CCS. The reason for this is due to history. Djikstra, a controversial yet respected (he's a Turing Award winner, for example) professor of computer science, once famously said
Back in the day, it was better understood what "computer science" formally is: an adjacent field to mathematics.
The problem came once there became industrial demand for software developers. How do we produce more of them? Well, computers already were heavily tied to universities, and universities teach things. So it sort of became expected that Computer Science departments would teach programming.
But (and this is arguable, but I'm not going to go in depth about the debate right now) even "software engineering" is a bit of a misnomer: software development is more akin to a trade, or a craft, than an engineering or science discipline. Yes, your random software developer makes use of the intellectual developments of the more theoretical minded computer scientists, and there's good reason to employ those kinds of folks as well. But the skillsets are nearly entirely disjoint.
And that means that a degree in computer science, looking purely at the "do you know how to work as a job as a software developer" aspects, are massively inadequate. Moreover, professors often feel a bit duped, or at least, they did back in my day: they came here to do math, not teach people how to write tests. They often do not have the industry experience to be able to properly teach techniques that are critical to industry, let alone have the institutional support to create courses based on such.
And that's how we got to the place of there being "coding schools," of which the quality wildly varies, but often aren't very good, but at least even the bad ones give you some sort of introduction to topics that serve you as a working programmer.
There are also some very interesting experiences on this regardless of the larger structural issues. Harvey Mudd College sought to increase the number of students who decide to pursue a computer science degree. As an engineering college, most students take an introductory computer science course. Yet many decided to pursue other majors, even if they came into the school with the intention of pursuing computer science. They decided to take an interesting approach to fixing this issue: on applying, students would indicate if they had ever written a program on their own before. The only change the administration made was to run classes where they would put like with like; the experienced people in one class, and the unexperienced in the other class. No course material changes were made, no changes in teaching staff or techniques.
What they found was a meaningful increase in the decision to pursue computer science as a major. And what's more, they also found this led to more gender equality in the CS student body, because it was more likely that men had previous experience, and so the benefit often went even further among non-men.
Why did this work? Well, if you've programmed before, introductory classes are trivial for you. And the result is, when asking questions in the classroom, you instantly know the correct answer, 100% of the time. You don't struggle with homework. You get great grades. All with ease. Yet your classmates for whom this is all new, have to put in work. They don't know every answer quickly. And so they go "oh, this is hard for me, and easy for others. This must not be for me." And change majors. Simply by separating these two groups, their experiences of the classes were much, much better, and folks who had the desire plus the ability to pursue a degree were no longer discouraged.
Anyway, the point here is just that this stuff is tremendously difficult, which doesn't mean that we shouldn't continue to try.
Another challenge in my experiences here has been the uncharitably of programmers towards those working in mixed disciplines. A friend of mine once quipped "Programmers are like compilers: they read blog posts until they find the first issue they disagree with, and then they stop reading, and error out by posting about how bad this blog is on twitter." Combined with a poor lack of understanding of the basic analytic techniques of the humanities, they often just refuse to meaningfully engage with CCS related topics. I am reminded once of when a previous CCS WG thread was linked on a programmer related forum; I saw people complaining about how "stupid" the discussion was. I followed the link, and lo and behold, it was one in which I had participated! The discussion was fine, it's just that these people would outwardly reject a statement like "can code be feminist or misogynist" at its face, and do not posses the intellectual tools to even evaluate the arguments being made, yet have no issues haughtily discounting something they do not even understand.
This dynamic prevents both the necessary environment to facilitate knowledge creation, but also skills transfer: I would love to see those who are more on the "programmer" side help those who don't have as much of a background achieve those skills, and vice versa. Unfortunately, I suspect that this culture isn't going to change any time soon, and so we should cherish what we have going on here.
Intra-disciplinary studies is just very challenging.
To help people understand how the ELIZA program produces a response to user input you can use the * and ** commands on the implementation here. E.g.
The user types line 1 and gets the response on line 3. The user uses the asterisk command on line 5 to get a trace of the steps ELIZA took to produce that response. The user types ** on line 22 to get the specific DOCTOR script rules used to generate the response. Students can write their own scripts for ELIZA and run them with the *load command.
Thanks everyone for sharing, very interesting and rich materials!
One short contribution: I taught a course on the relationship between politics and code and, even though I had only one session dedicated to the implications and challenges of critical code studies, I had good results in grabbing the students' interests in source code by having them write code rather than read code.
Since the course involved practical projects in JS, students had a good foundation in classes/methods/functions, so I gave them the prompt to "describe war in a single class".
You can see the results here: https://github.com/periode/politics-of-code/tree/master/12_misc-semantic-code/war
After they completed the in-class exercise, we follow with a critique of each other's codes, and a discussion on approaches to modeling the problem, challenges in translating human concepts to machine code. This proved to be quite successful, and I would recommend its integration in a curriculum!
At my previous institution (which had a strong computer science & engineering college), in one semester I taught a course on exploring code with an eye toward its rhetorical dimensions, affordances, and constraints. The target student audience was undergraduate humanities students, and no prior code-related technical knowledge was required.
We primarily focused on key concepts and how they might play out computationally in relation to more conventional forms & genres of communication. This included issues like rhetorical style, delivery, iterative drafting/revising (and what that looked like in practice for a lot of collaborative open source projects/communities), and various questions about access & accessibility to CS resources, technologies/platforms, privilege & bias influencing the construction of a given program, and so on.
For class-related programming experimentation, we made use of Processing, with a lot of relevant discussion about the nuances of different languages and what that would mean for students' efforts to examine other programmers' code (however similar the language might be to what they were learning).
There was significant interest among the students in the class to explore ways they could attempt to effect social change through their code/programs but also in the code itself, the latter in terms of how their procedural work was named, described, organized, and commented on. I had the unanticipated benefit of teaching during an election season, and students in the class were eager to engage not only their school community but the broader citizenry with the projects they developed (such as working on ways to provide compelling real-time visualizations of Twitter data about public support for/against some key bills on the ballot).
I recall the semester ending with a simultaneous sense of enthusiasm and frustration about what they wanted to do, what they were able to do, and how separate that particular class felt to many of them compared to the rest of their studies.
At my current institution there have been occasional course offerings from CS professors for humanities-related CS study, but I wouldn't necessarily describe that as CCS-related; the goal for them has tended to be more pragmatically centered instruction to assist with learning how to make use of natural language processing tools and the like.
In the course I taught here at USC, we used the following books:
Critical Code Studies, Marino
Aesthetic Programming, Cox and Soon
10 PRINT CHR$(205.5+RND(1)); : GOTO 10, Montfort et al.
Travesty Generator, Bertram
Poetic Operations, Cardenas
Race After Technology, Benamin
If Hemingway Wrote JavaScript, Kroll
#!, Montfort
We also drew heavily from the first Critical Code Studies special issue of DHQ and will probably add the second special issue next time around.
If Hemingway Wrote JavaScript was really the breakthrough in terms of getting students do try out their own readings. For their first paper, students chose one of those code pieces and did a close reading in terms of what the piece said about JavaScript and about the writer being parodied(?) or paid homage to.
Currently, I'm thinking of swapping in a new intro to programming text, as I mentioned previously, but I still would want to assign at least some of Aesthetic Programming because of the way it models tying programming concepts into larger themes.
What other texts would people include?
In my courses, I teach students from the fields of educational science, teacher and media education, media studies, as well as computer science and computational visualistics. Interdisciplinarity and openness play a crucial role in these classes. No two courses are the same, as I outline the topics broadly but allow students in the initial sessions to delve deeper into specific subjects of their choice, such as creative coding, bias in data, and gender and code. I work with the introductory book by Mark (Critical Code Studies), but also incorporate literature from authors like Winnie Soon and Geoff Cox (Aesthetic Programming), and the works of Adrian Mackenzie are also significant in my curriculum.
Since I try to combine topics of cyber security with critical code studies, hacks and their media representations, also media cultures have been topics in my sessions. There is a vital link between the concept of education and ethical considerations.
As Jack Mezirow puts it with transformative learning: the concept suggests that individuals can change their fundamental perspectives on the world through a process of critical reflection and personal experience, the concept focuses on how individuals can challenge and revise their existing beliefs, assumptions, and values, leading to a more inclusive, discriminating, and integrative perspective. According to Mezirow, the process often begins with a "disorienting dilemma", a situation or experience that cannot be explained or addressed with the learner's current understanding or worldview, with uncertainty or indeterminacy. This leads to a period of reflection, during which the individual questions their preconceived notions and the validity of their assumptions and values. Through dialogue with others and further reflection, learners explore new ways of interpreting their experiences, which can result in a transformation of their perspective. Taking such a concept of education into account, teaching code goes beyond functional programming and discussing cultural implications becomes a platform for reflection of societal challenges as well as educational practices.
In addition to collaborative coding reviews, which we've recently implemented using GitHub codespaces, I rely on short essays and structured tasks related to the texts we discuss in the sessions. This approach not only fosters a deep understanding of the data and text but also encourages a critical perspective on the intersection of technology, culture, and society.
When teaching coding to non-technical students, I think it's crucial to adopt approaches that simplify and demystify the process. I know, that this is tricky and not trivial, but starting with visual programming languages like Scratch can make initial concepts more accessible. Relating coding projects to real-world applications that interest students can also spark engagement, while using high-level, syntax-friendly languages such as Python introduces programming in a straightforward manner. I have had good experiences with code examples in Python. Also, incorporating interactive learning platforms, project-based learning, and emphasizing soft skills like problem-solving enhances the learning experience and quality. In my courses, I try to settle a collaborative environment through peer learning, where I also provide quite a lot of resources for self-directed learning and exploration. By making coding relevant and engaging, I experienced, that students are more likely to develop a lasting interest and understanding of the subject and its complexity.