<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
      <title>CCSWG: Critical Code Studies Working Group 2020</title>
      <link>http://wg20.criticalcodestudies.com/index.php?p=/</link>
      <pubDate>Fri, 10 Apr 2026 18:06:40 +0000</pubDate>
          <description>CCSWG: Critical Code Studies Working Group 2020</description>
    <language>en</language>
    <atom:link href="http://wg20.criticalcodestudies.com/index.php?p=/discussions/feed.rss" rel="self" type="application/rss+xml"/>
    <item>
        <title>Platforms for writing Interactive Fiction: Ink, ChoiceScript, Inform, Tads  (Code Critique)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/67/platforms-for-writing-interactive-fiction-ink-choicescript-inform-tads-code-critique</link>
        <pubDate>Mon, 27 Jan 2020 03:14:28 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">67@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>There are so many great languages for writing interactive fiction.  I wanted to start a thread for discussing the merits of these languages.  Let's use this thread to compare them.</p>

<p>Would it be useful to compare features?  Or compare passages of code that create the same effects? Also, I wonder if we should narrow this thread to the first two, since at least Inform 7 is quite different.</p>

<p>Perhaps we could begin with this question? Which is your favorite language (or favorite aspect of a language) for authoring interactive fiction and why?</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Hitchhiker's Guide to the Galaxy</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/66/code-critique-hitchhikers-guide-to-the-galaxy</link>
        <pubDate>Fri, 24 Jan 2020 13:22:22 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">66@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Software: Hitchhiker's Guide to the Galaxy (Game)<br />
Authors: Steve Meretzky and Douglas Adams<br />
Language: ZIL: Zork Implementation Language<br />
Year: 1984<br />
Source file: <a href="https://github.com/historicalsource/hitchhikersguide/blob/master/heart.zil" rel="nofollow">https://github.com/historicalsource/hitchhikersguide/blob/master/heart.zil</a><br />
Code repository: <a href="https://github.com/historicalsource/hitchhikersguide" rel="nofollow">https://github.com/historicalsource/hitchhikersguide</a><br />
Zil Code Manual: <a href="https://archive.org/details/Learning_ZIL_Steven_Eric_Meretzky_1995" rel="nofollow">https://archive.org/details/Learning_ZIL_Steven_Eric_Meretzky_1995</a></p>

<p>The Hitchhiker's Guide to the Galaxy was a text adventure game based on the book/radio/television series that was known in the universe for serving puzzles that made you want to smash your brain with a brick wrapped in a lemon. See <a rel="nofollow" href="https://news.ycombinator.com/item?id=21134638" title="this discussion">this discussion</a> for some common reactions.  In this puzzle, and this is a spoiler, you need to have previously removed your common sense so that you can at once have "tea" and "no tea" in your inventory.</p>

<p>I wanted to start a thread to invite you all on a sidequest to explore the code of this game that I encountered at a very formative time of my life.  Pretty much influenced everything I do as an e-lit artist. But I do recognize (especially having tried to teach it) that this game goes beyond the usual level of frustration-inducing puzzles that <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/profile/jeremydouglass">@jeremydouglass</a> has written about.  <a rel="nofollow" href="https://www.reddit.com/r/programming/comments/benb0r/you_can_now_download_the_source_code_for_all/" title="Some argue">Some argue</a> that the difficulty of the puzzles was tied to a profit motive -- selling more hint books, increasing gameplay time.  A later game from Adams, Bureaucracy, would make frustrating puzzles its main theme. I'm not sure this is the best passage to start with, but I'd like to use this to open a code exploration of this game and perhaps also The Restaurant at the End of the Universe code, which I am just learning exists!</p>

<pre><code>&lt;ROUTINE SCREENING-DOOR-F ()
     &lt;COND (&lt;EQUAL? ,SCREENING-DOOR ,WINNER&gt;
        &lt;COND (&lt;AND &lt;VERB? TELL-ABOUT&gt;
                &lt;PRSO? ,ME&gt;&gt;
               &lt;SETG WINNER ,PROTAGONIST&gt;
               &lt;PERFORM ,V?ASK-ABOUT ,SCREENING-DOOR ,PRSI&gt;
               &lt;SETG WINNER ,SCREENING-DOOR&gt;
               &lt;RTRUE&gt;)
              (&lt;VERB? HELLO&gt;
               &lt;SETG WINNER ,PROTAGONIST&gt;
               &lt;PERFORM ,V?HELLO ,SCREENING-DOOR&gt;
               &lt;SETG WINNER ,SCREENING-DOOR&gt;
               &lt;RTRUE&gt;)
              (&lt;AND &lt;VERB? WHAT&gt;
                &lt;PRSO? ,OBJECT-OF-GAME&gt;&gt;
               &lt;SETG WINNER ,PROTAGONIST&gt;
               &lt;PERFORM ,V?ASK-ABOUT ,SCREENING-DOOR ,OBJECT-OF-GAME&gt;
               &lt;SETG WINNER ,SCREENING-DOOR&gt;
               &lt;RTRUE&gt;)
              (T
               &lt;TELL
&quot;\&quot;Unless you're here to show me some clear sign of your intelligence, please
leave me alone. I'm a very busy door.\&quot;&quot; CR&gt;
               &lt;FUCKING-CLEAR&gt;)&gt;)
           (&lt;AND &lt;FSET? ,SCREENING-DOOR ,OPENBIT&gt;
             &lt;VERB? SHOW GIVE KNOCK OPEN&gt;&gt;
        &lt;TELL &quot;You already induced the door to open.&quot; CR&gt;)
           (&lt;AND &lt;FSET? ,SCREENING-DOOR ,OPENBIT&gt;
             &lt;VERB? CLOSE&gt;&gt;
        &lt;TELL
&quot;The door snaps, \&quot;Hey! I'm resting. I've had a very busy day.\&quot;&quot; CR&gt;)
           (&lt;VERB? KICK&gt;
        &lt;FSET ,SCREENING-DOOR ,MUNGEDBIT&gt;
        &lt;TELL
&quot;\&quot;I suppose you think that since you have legs and I have not, you can get
away with that sort of thing. Well,\&quot; the door continues stiffly, \&quot;maybe you
can and maybe you can't.\&quot;&quot; CR&gt;)
           (&lt;VERB? SHOW GIVE&gt;
        &lt;COND (&lt;AND &lt;PRSO? ,TEA ,NO-TEA&gt;
                ,TEA-SHOWN
                &lt;HELD? ,TEA&gt;
                ,HOLDING-NO-TEA
                &lt;NOT &lt;PRSO? ,TEA-SHOWN&gt;&gt;&gt;
               &lt;PERFORM ,V?KNOCK ,SCREENING-DOOR&gt;
               &lt;RTRUE&gt;)
              (T
               &lt;COND (&lt;PRSO? ,TEA ,NO-TEA&gt;
                  &lt;SETG TEA-SHOWN ,PRSO&gt;)&gt;
               &lt;COND (&lt;PROB 50&gt;
                  &lt;TELL
&quot;The door says \&quot;Big deal. Anyone can have&quot;&gt;
                  &lt;ARTICLE ,PRSO&gt;
                  &lt;TELL &quot;.\&quot;&quot; CR&gt;)
                 (T
                  &lt;TELL &quot;The door yawns.&quot; CR&gt;)&gt;)&gt;)
           (&lt;VERB? OPEN KNOCK&gt;
        &lt;COND (&lt;AND &lt;HELD? ,TEA&gt;
                ,HOLDING-NO-TEA&gt;
               &lt;FSET ,SCREENING-DOOR ,OPENBIT&gt;
               &lt;TELL
&quot;The door is almost speechless with admiration. \&quot;Wow. Simultaneous tea
and no tea. My apologies. You are clearly a heavy-duty philosopher.\&quot; It
opens respectfully.&quot; CR&gt;)
              (T
               &lt;TELL
&quot;The door explains, in a haughty tone, that the room is occupied by a
super-intelligent robot and that lesser beings (by which it means you)
are not to be admitted. \&quot;Show me some tiny example of your intelligence,\&quot;
it says, \&quot;and maybe, just maybe, I might reconsider.\&quot;&quot; CR&gt;)&gt;)
           (&lt;AND &lt;VERB? ASK-ABOUT&gt;
             &lt;PRSI? ,OBJECT-OF-GAME&gt;&gt;
        &lt;TELL &quot;\&quot;To keep out sub-intelligent beings.\&quot;&quot; CR&gt;)
           (&lt;VERB? THROUGH&gt;
        &lt;COND (&lt;EQUAL? ,HERE ,PANTRY&gt;
               &lt;DO-WALK ,P?EAST&gt;)
              (T
               &lt;DO-WALK ,P?WEST&gt;)&gt;)
           (&lt;VERB? EXAMINE&gt;
        &lt;FCLEAR ,SCREENING-DOOR ,ACTORBIT&gt;
        &lt;V-LOOK-INSIDE&gt;
        &lt;FSET ,SCREENING-DOOR ,ACTORBIT&gt;)&gt;&gt;
</code></pre>

<p>A few questions:<br />
How does this code speak to the frustration-inducing nature of the game?<br />
What does this code reveal about ZIL as a language?<br />
Or does this code show that the game is just terribly misunderstood?<br />
Is this a representative passage from the game?<br />
How does this compare with puzzles of other Infocom games of the time?<br />
What other passages of the HGTTG code should we explore?</p>
]]>
        </description>
    </item>
    <item>
        <title>Week 3: Feminist Search (Code Critique)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/88/week-3-feminist-search-code-critique</link>
        <pubDate>Mon, 03 Feb 2020 23:14:19 +0000</pubDate>
        <category>2020 Week 3: Feminist AI</category>
        <dc:creator>Christine.Meinders</dc:creator>
        <guid isPermaLink="false">88@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>by Christine Meinders, Jana Thompson, Sarah Ciston, Catherine Griffiths</p>

<p><strong>Approaches to Co-Creation </strong><br />
In this example, community-sourced data can be traced both visually and in code, and can be used to inform the very model used to process this information. Rather than simply coding, the prototyping process is incorporated in the code from a critical perspective. This process is guided by the <a rel="nofollow" href="https://aidesigntool.com/">Cultural AI Design Tool</a>, which refocuses the design process so that questions of creator, data origin, and rule-creation are centered rather than marginally examined or ignored. Using these as a basis for this particular critical code context, contributors are credited, while also keeping the prototype open for co-creation and reformulation by the community.</p>

<p><strong>Modeling Binaries:</strong> <br />
There are several pieces that contribute to <em>Feminist Search</em>:<a rel="nofollow" href="https://aidesigntool.com/feminist-search">  personal data donation</a>, interface design, and the use of binaries in data collection and model creation.   </p>

<p>The <em>Feminist Search</em> project explores what is safe and what is dangerous. Binary notions of safety and danger are just the starting point. Within the last five years, rising dangerous rhetoric is becoming socially acceptable once more and a corresponding rise in violent acts globally. Beyond this, there are the pressures of misogyny, racism, and other forms of bigotry that increase an individual or community's constant awareness of action to make themselves safe. What makes people feel safe? Safety can be categorized differently, such as physical, emotional and professional safety. </p>

<p>These binary definitions can be expanded by examining the grey spaces with the questions in the personal data donation. By having people discuss what safety means to them, or semantics of this term and related concepts, models can be built that reflect these spectrums, that allows for both exciting design and technical challenges, but more importantly, for creating technology that is for the people who contribute their data. <em>Feminist Search</em> explores the challenges of search from a community perspective---with a goal of reflecting the shared data of communities in Los Angeles and San Francisco. </p>

<p>One highlight is that computation is fundamentally binary, as are labels in machine learning---the data donation portion of <em>Feminist Search</em> uses labels of safe and dangerous. However, the goal is to move beyond a true/false dichotomy, because truth value in subjective particularly in categorizations of feelings and sentiments.</p>

<p>For those who are not familiar with the details of machine learning, fundamentally, machine learning is mathematical representations of geometric spaces that have distance functions as part of their definition. In defining geometric  classes, there will be a division between classes in an n-dimensional space (as in linear regression), or instead perhaps something such as a centroid in a clustering algorithm that will be the most representational of a cluster. Prediction(s) as to a class or type of image will depend on the geometric location in the vector space of the item(s).  </p>

<p>The interesting problems in data science and machine learning aren't in churning out mathematically good predictions, however. The outcome of an algorithm is only as good as the data given to it and how the person(s) constructing it use that data in the creation of a model. What often happens in construction of models is that outliers from other data points are often thrown out or are drowned out in the majority vote of the more "normal" considerations. Thus, these lead to models where a literal tyranny of the majority can happen, since the majority of opinions have more weight statistically - instead of treating all the data equally. </p>

<p>In this approach, the simple act of search can be used to understand binary decisions that are used to form a model, and how users can donate information to understand who is contributing to search and data collection. This is the central starting point that prioritizes visualization and creates a space to develop a community search engine. In <strong>Feminist Search</strong>, communities create and provide contexts for evaluation, with the goal of sharing these decisions along with donated personal data, and the "why" in the search results. </p>

<p>An additional goal of <em>Feminist Search</em> is to highlight thoughtful data donation and model weighting processes, while also showing how search is used---thus incorporating Feminist.AI approaches by exploring the act of search by utilizing embodied, multi-sensory (movement, sound, and images) methods through critical prototyping. <em>Feminist Search</em> is a way to solidify and continually honor the work of feminist communities.</p>

<p>Here is the code for <a rel="nofollow" href="https://github.com/FeministAI/feminist_search">Feminist Search</a><br />
<em>Thompson, 2020, Python</em></p>

<pre><code>import numpy as np
import cv2
import glob
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV

def  import_image(path):
    &quot;&quot;&quot;
    INPUT: path to image file in jpg
    OUTPUT: machine readable image file
    &quot;&quot;&quot;
    image = cv2.imread(path)
    return image

class  ClusteredImages:
    def  __init__(self, positive_images_path, negative_images_path, image_suffix, number_of_clusters):
    self.positive_images = set(glob.glob(positive_images_path + '/' + image_suffix))
    self.negative_images = set(glob.glob(negative_images_path + '/' + image_suffix))
        self.no_of_clusters = number_of_clusters

    self.image_paths = [[path, True] for path in self.positive_images] + [[path, False] for path in self.negative_images]
        self.image_array = np.array(self.image_paths)
        
    self.descriptors = []
        for path, label in self.image_array:
            image = import_image(path)
            b_and_w = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            sift = cv2.xfeatures2d.SIFT_create()
        kp, each_descriptors = sift.detectAndCompute(b_and_w, None)
            self.descriptors.append(each_descriptors)

    def  return_labels(self):
        return np.array(self.image_paths)[:, -1]

    def  generate_features(self, clustering_model):
            # rename function to reflect that it returns both training data and predictable data
            number_of_clusters = clustering_model.n_clusters
        descriptors_pre_array = [desc for desc_list in self.descriptors for desc in desc_list]
            descriptors_array = np.array(descriptors_pre_array)
            clustering_model.fit(descriptors_array)
        clustered_words = [clustering_model.predict(words) for words in self.descriptors]
            return np.array([np.bincount(words, minlength=number_of_clusters) for words in clustered_words])

class  ParameterFinder:
        def  __init__(self, X, y):
            # use gammas for rbf, poly and sigmoid
            #degrees for poly
            self.X = X
            self.y = y
            self.kernels_to_try = ['linear', 'rbf', 'poly', 'sigmoid']
            self.C_params = [0.001, 0.01, 0.1, 1, 10]
            self.gamma_params = [0.001, 0.01, 0.1, 1]
            self.degree_params = [0.0, 1.0, 2.0, 3.0, 4.0]
        
    def  find_best_params(kernel, X, y, param_grid):
                grid_search = GridSearchCV(svm.SVC(kernel = kernel), param_grid)
                grid_search.fit(X, y)
                return grid_search.best_params_

        def  return_all_best_params(self):
            best_params = {}
                # should rewrite to pass kernel and find parameters
                for kernel in self.kernels_to_try:
                    if kernel == 'linear':
                            param_grid = {'C': self.C_params}
                            search_for_params = find_best_params('rbf', self.X, self.y, param_grid)
                            best_params['linear'] = search_for_params
                    elif kernel == 'rbf':
                            param_grid = {'C': self.C_params, 'gamma': self.gamma_params}
                            search_for_params = find_best_params('rbf', self.X, self.y, param_grid)
                            best_params['rbf'] = search_for_params
                    elif kernel == 'poly':
                            param_grid = {'C': self.C_params, 'gamma': self.gamma_params, 'degree': self.degree_params}
                            search_for_params = find_best_params('poly', self.X, self.y, param_grid)
                            best_params['poly'] = search_for_params
                    else:
                            pass
        return best_params
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: AI and Animal Experimentation reading in Protosynthex III, 'There is a Monkey'</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/95/code-critique-ai-and-animal-experimentation-reading-in-protosynthex-iii-there-is-a-monkey</link>
        <pubDate>Fri, 07 Feb 2020 18:57:44 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Lesia.Tkacz</dc:creator>
        <guid isPermaLink="false">95@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Title: ** Protosynthex III, Example 3 in ‘A Deductive Question-Answerer for Natural Language Inference’, <a href="https://dl.acm.org/doi/10.1145/362052.362058" rel="nofollow">https://dl.acm.org/doi/10.1145/362052.362058</a><br />
**Authors:</strong> Robert M. Schwarcz, John F. Burger, Robert F. Simmons<br />
<strong>Languages:</strong> Protosynthex III, perhaps LISP?<br />
<strong>Year:</strong> 1970</p>

<p>I’ve been looking through a copy of Jean Sammet’s <em>Programming Languages: History and Fundamentals</em> (1969), particularly the sections on string processing languages and specialty languages. The latter contains a description of Protosynthex, which is a language designed to be used for question answering tasks. I was curious about this language because I’m interested in the history of AI, and 1960s AI research seems to have been tied very closely to linguistics and logical reasoning - arguably much closer than it is today. The Protosynthex code example in Sammet’s book is quite short, and it’s been difficult to find more examples. I did manage to find some example uses of Protosynthex III in a research paper from 1970 titled ‘A Deductive Question-Answerer for Natural Language Inference’, by Schwarcz, Burger, and Simmons. I’ve taken screenshots of the example code in <em>Example 3</em> and included it in this thread as a PDF. I've also included the paper, where the code can also be read from pages 181-182. It’s not clear to me whether Protosynthex III is a distinct language like Protosynthex is, or if it is actually a form of the LISP language.</p>

<p>What I find interesting about the example code in _Example 3 _ (pp. 181-182), which I’ll call ‘There is a Monkey’, is that it appears to play out a scenario which could be seen in an animal experiment. ‘There is a Monkey’ declares a monkey, a box, and bananas. The bananas are positioned in such a way that they are only to be reached if the box is moved <code>TO THE BANANAS</code>. Towards the end of the example code a query reads <code>DOES THE MONKEY GET THE BANANAS?</code>, with the final line of code stating <code>MONKEY REACH BANANAS.</code> . The paper states that this example is “...adapted from an Advice Taker problem proposed by [John] McCarthy” (p. 174) in his ‘Situations, actions, and causal laws’, found in Stanford Artificial Intelligence Project Memo No. 2, July 1963. McCarthy is the inventor of the LISP language, which has been historically very popular in AI.</p>

<p>There’s no background given about why or how the monkey, box, and bananas have been brought together, what their size and distance from each other is, why or how the bananas are suspended, nor any information about where this event or simulation is taking place. Indeed, we do not really know if <code>(THERE . PLACE)</code> on line 7 even has a floor or walls, but <strong>I suspect that most people who read this code will assume that the event or scenario is not taking place in a monkey’s natural environment (do you agree or disagree?).</strong> This event or simulation could have instead easily been written by declaring a climbing tree instead of a box, but for whatever reason a human made object is declared as the means or tool for reaching the bananas. This seems very unnatural, as if an animal is being observed and tested in an experiment environment in order to collect evidence or to prove something. Of course, the actual purpose of this code is to prove or demonstrate what types of question answering experiments can be conducted using Protosynthex III. However, this in itself does not explain why a linguistic and AI experiment is performed as an event or simulation set up in a minimal, controlled environment designed to test if a monkey will reach its food. I therefore find it curious that the emerging field of AI in the 1960s would reproduce controversial forms of experimentation as seen in biology and psychology in its models. Perhaps there is a prestigious ‘scientific aesthetic’ that is trying to be emulated. Perhaps it’s just following what is perceived to be a convention. <strong>Perhaps you can see other readings?</strong></p>

<p>The paper offers its own explanation of ‘There is a Monkey’, which I’ve copied here: <br />
“<em>Explanation.</em> The monkey gets the bananas if he reaches them, and he can reach them if he stands on an elevated object under them and reaches for them; the monkey stands on the box, which is an elevated-object, and reaches for the bananas, and so if the box is under the bananas the monkey has succeeded in reaching them; the box is under the bananas if it is lower than they, which it is, and also at the bananas; the box is at the bananas if some animal has moved it to the bananas--which of course the monkey has done; therefore, the monkey reaches the bananas. The question-answerer follows just this reasoning path in answering the question (though in terms, of course, of the formal concept structure) ; the recombination of subgoal answers into an answer to the question is shown by the trace of STOGOAL in the Appendix. It is interesting to note here, of course, the input of inverses (converses) and inference rules by means of English sentences; with a few additional grammar rules and pieces of lexical information, properties could be input in this manner also”(p. 176).</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique / Book Review: Travesty Generator by Lillian-Yvonne Bertram</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/99/code-critique-book-review-travesty-generator-by-lillian-yvonne-bertram</link>
        <pubDate>Sun, 16 Feb 2020 13:35:04 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>zachwhalen</dc:creator>
        <guid isPermaLink="false">99@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Hello,</p>

<p>I have recently read Lillian-Yvonne Bertram's excellent new book of poetry, <a rel="nofollow" href="https://www.lillianyvonnebertram.com/travesty-generator"><em>Travesty Generator</em></a>. I started writing a short book review for CCSWG, but I just kept digging into it. So what follows is my hastily-written and barely-edited analysis of three of its poems. I'm interested in discussing this book and in whatever conversation my analysis/review may lead to here, but I mainly want to post this because I think this community will dig this book too and I wanted to make sure more people know about it.</p>

<p>What follows is pretty rough, so I will probably copyedit and refine it somewhat after posting.</p>

<hr />

<p>Lillian Yvonne-Bertram's book of poetry is titled <em>Travesty Generator</em> (Noemi Press, 2019) in reference to Hugh Kenner and Joseph O'Rourke's Pascal program to "fabricate pseudo-text" by producing text such that each n-length string of characters in the output occurs at the same frequency as in the source text. By combining different authors through this algorithm, one might stumble across a travesty of "haunting plausibility" wherein James Joyce's writing becomes muddled with Henry James'. The pseudo-text's nonsensibility is simultaneously its transgression and its literary possibility, but for Kenner and O'Rourke and the many progeny of their program, those possibilities extend no farther than a formal curiosity or at best an insight into an author's poetic style.</p>

<p>When Charles O. Hartmann uses Travesty in his <em>Virtual Muse</em>, he finds that the nonsense it generates helps Hartmann's composition process by disrupting the habits he found himself following as a writer. Of the generator itself, Hartmann noted with some awe that "here is language creating itself out of nothing, out of mere statistical noise" (63).</p>

<p>What Bertram accomplishes in naming her book after travesty generator is to raise the stakes in computer-generated poetry. Whereas for Kenner and O'Rourke, labeling their work a "travesty" is a hyperbolic tease, a literary burlesque, for Bertram, the word is reinvigorated with a feeling of its political reality. In 2013, attorney Don West, responding to the not guilty verdict for his client George Zimmerman in the shooting death of Trayvon Martin, congratulated the jury for keeping "this tragedy from becoming a travesty." West is implying that the media attention on the case risked creating what he and Zimmerman would have called a farcical miscarriage of justice for his client.</p>

<h2>"Counternarratives"</h2>

<p>For others, the event was always a travesty: a "grotesque parody or imitation" of criminal justice enacted by a civilian playing at being a law enforcement officer that resulted in an extra judicial killing of an unarmed high-school student.</p>

<p>Central to anyone's response to that verdict is how one understand the narrative of events on February 26, 2012. This is question Bertam takes up in her poem "Counternarratives" which presents sentences, fragments, and ellipses that begin ambiguously but quickly resolve into a series of hints, implications, and images around Trayvon Martin's killing. These narratives are "counter" for several reasons, most importantly for the fact that they include Martin's point of view:</p>

<blockquote><div>
  <p>He never told anyone, but he always wanted to go to space camp.<br />
  ...<br />
  He rides from station to station until he can rest at home.<br />
  ...<br />
  Sometimes he wakes feeling gone and doesn't know why.</p>
</div></blockquote>

<p>Bertram prints these sentences with others in 14 successive stanzas, each printed on its own face of a page, each growing in size until the blank 13th stanza breaks the pattern. One can see the inertia of automation and the inevitability of processes at work in the consistency of this pattern and in the way the poem intersects other perspectives that include the algorithmic prompts of search engines ("People also ask: <em>what really happened?</em>") and the horticultural ("Only the flowering catalpa trees are on watch") -- all echoes of the machinic "generator" in the book's title. But because this is literally generated from computer code, these observable processes yield two other significant "counters" at work.</p>

<p>Bertram does not share the source code for this poem, but in an appendix acknowledges that it is adapted from the Python version of Nick Montfort's poem, "Through The Park," published in his 2014 collection <em>#!</em> and available on his website. Montfort's poem is framed by a <code>for</code> loop, or a "counter," <code>i</code>, iterating through 8 sequences, each of which prints a numbered stanza:</p>

<pre><code>for i in range(8):
</code></pre>

<p>For each loop and each stanza, the program selects a number  7 - 11 (<code>phrases = 7 + random.randint(0,4)</code>) and randomly deletes lines from the initial 25 unti the lines that remain reach the selected number of <code>phrases</code>, joining those remaining lines with ellipses. The resulting poems achieve their meaning through omission, elision, and innuendo, relying on the ambiguity of language and the way readers respond to that ambiguity by imagining the context that creates the poem's implied narrative. What that narrative is will depend on which lines end up being printed, and in <em>#!</em>, the 8 stanzas that Montfort selects show how widely those contexts may diverge, and these could range from a casually flirtatious encounter with a stranger to a sexual assault. The latter reading is activated by whether two or three key phrases are chosen to remain in the resulting poem. The suggestive phrases "The girl puts on a slutty dress", "The man makes a fist behind his back," "The man's breathing quickens," and "The man dashes, leaving pretense behind" makes "The girl's bag lies open" metonymic and lets the question of what their glances know "The man and girl exchange a knowing glance" hinge the meaning of the moment toward violence.</p>

<blockquote><div>
  <p>The girl puts on a slutty dress. ... A wolf whistle sounds. ... The muscular man paces the girl. ... A wildflower nods, tightly gripped. ... Laughter booms. ... A lamp above fails to come on. ... The girl's bag lies open. ... A patrol car's siren chirps. ...</p>
</div></blockquote>

<p>This violence is implied, but generic, and the poem's meaning is about the way language gives shape to violence. The victim blaming in the "slutty dress" line, for example, is Montfort reminding us of the ways that words create an inertia of belief that precedes knowing. Ultimately, however, this is all that is stake for the poem.</p>

<p>Bertram's "Counternarratives" is more than an adaptation of Montfort's because it is also a counter to "Through the Park." Whereas the context for Montfort's poem is hypothetical, Bertram's is real and specific. While we cannot consult Bertam's source code, it is possible to imagine the process whereby Montfort's "A wildflower nods, tightly gripped" becomes Bertram's "The frangipani swans in the moonlight" and Montfort's "She puts on a slutty dress" becomes "People also ask what he was wearing." or perhaps "No mention of his clothing."</p>

<p>What Trayvon Martin wore -- a hoodie -- became a symbol for that event and a meme for Black Lives Matter because of its power in calling out racial profiling. The assumption that a "black man with a hoodie" is inherently threatening is conveyed in Bertram's "People also ask..." phrasing, which quotes a google search suggestion. In the context created by this poem, this question recalls the victim blaming in Montfort's poem's "slutty dress" line, but following Bertram's move from the generic to the particular, this search suggestion and other's like it are drawn from reality.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/4u/yfb999cy4uhb.png" alt="screenshot of search results including &quot;people also search for: what was Trayvon Martin wearing?&quot;" title="" /></p>

<p>After a few trials, I discovered the suggestion "What was Trayvon Martin wearing?" in response to the search query "Who shot Trayvon Martin?". I also found another recurring line, and the final line in Bertram's poem, "People also search for: <em>Emmett Till</em>" come up in several similar searches. This is a demonstration of the way that search engines, like language, become the machinery for racial violence through their operationalization of algorithmic bias. Notably, Bertram's line does substitute Martin's name for the pronoun "he," so the antecedent could be Zimmerman, especially since neither are named outright in the poem. This final opening out of meaning is another significant way in which the poem reflects on its constructedness.</p>

<p>In the book's appendix, Bertram notes that the output of her program has been edited and arranged, and this rewriting is evident in the way that certain of the phrases evolve as the poem progresses. In some cases, this is an evolution that follows a trajectory implied to begin in Montfort's version which has its possible final line, "A patrol car's siren chirps."</p>

<p>Bertram's lines (never the last for any of her 14 stanzas) proceeds from there to</p>

<blockquote><div>
  <p>[3] ... A patrol car's siren sings several streets away...</p>
  
  <p>[10] ... Several weeks away, a patrol siren sings...</p>
  
  <p>[11] ... A patrol car's siren sings several streets way...</p>
  
  <p>[12] ... A patrol car's siren swats bugs and halos away...</p>
  
  <p>[14] ... A siren signs  <br /><br /> several streets away.</p>
</div></blockquote>

<p>The most striking movement in the poem is that way that "Counternarratives" uses ellipses. Whereas Montfort's poem is suggestive through the innuendo created by stochastic omission, Bertram's is subversive through the implications of its elisions, and those elisions and ellipses gradually resolve into prosodic syntax as the text of the poem gradually takes up its poetic mechanism. The phrase that first appears in stanza 4 as "Real gaps spread in the tropic of paradise" is stark in its proximity with its initial following line "Forty-two miles from Disney," where proximity here is both the poetic associations as well as the geopolitical identity of this Orlando suburb.</p>

<p>After the blank penultimate stanza -- a final elision -- this line has become "Gaps split open the tropic of paradise." A blank line splits the "siren signs" sentence, followed by the now damningly unambiguous "Cause of death: It was a gated community."</p>

<p>By editing and arranging the output of her program, Bertram is declining to let the machinery of language or Python control the narrative and opening up paths to resistance by insisting that we bear witness to the tragedy without retreating to the algorithmic distance of a travesty.</p>

<p>Two other poems in <em>Travesty Generator</em> offer similar insights on the relationship between the mechanization of computing and use those processes to interrogate the structures that make them possible.</p>

<h3>"three_last_words"</h3>

<p>The poem that opens the book, "three_last_words", is at a functional level a restatement of the program in Nick Montfort's "I AM THAT I AM", which is itself a version or adaptation of Brion Gysin's permutation poem of the same title. That phrase does not appear in Montfort's version. Rather, Montfort's program defines a <code>permutations</code> function and then executes that function with the string 'AEIOU' as its argument, yielding the 120 possible rearrangments of AEIOU as its outcome. Montfort's code accomplishes this succinctly through an elegant recursion as the <code>permutations</code> generator works through a list of <code>elements</code>, rearranging all of the following <code>elements</code> (<code>elements[1:]</code>) by passing them back into no more next <code>elements</code> remain.</p>

<p>"I AM THAT I AM" (from Montfort)</p>

<pre><code>def permutations(elements):
  if len(elements) == 0:
    yield elements
  else:
    for result in permutations(elements[1:]):
      for i in range(len(elements)):
        yield result[:i] + elements[0:1] + result[i:]
</code></pre>

<p>Bertram's generator is mostly the same, code but the commentary she adds -- and more importantly the uses she puts it to -- changes the meaning entirely. That new meaning is jarring and, as in "Counternarratives," tragic.</p>

<p>Bertram alternates lines of code with comments that accumulate toward something unavoidable:</p>

<p>"three_last_words" (excerpt) (Bertram)</p>

<pre><code>def permutations(elements):
#the
  if len(elements) == 0:
#the knife
    yield elements
   #the knife they
  else:
#the knife they hung
</code></pre>

<p>Eventually the completed sentences warns, "<code>#the knife they hung him on / #was a legal trinket</code>". When he was killed by Daniel Pantaleo while being placed under arrest, Eric Garner was selling loose cigarettes -- a minor violation of cigarette tax law. So "legal trinket" here brings to mind the way that Garner's alleged crime of selling cigarettes became a dog whistle for racist backlash to Black Lives Matter -- responses that included an Indiana police officer selling t-shirts with the mocking slogan, "Breathe easy, don't break the law." So a "trinket" because the relatively trivial infraction apparently justifies police violence.</p>

<p>"Trinket" does something else here as well, by naming a service, Trinket.io, which allows users to create snippets of Python code that they can embed and run in a webpage. This apparent reference hints at the practical environment for running this code, something that is unnecessary for Montfort's ontological poem because of its tautological symmetry.</p>

<p>Bertram's poem instead invites us to experience the consequences of her program with an explicit invitation a page later to</p>

<pre><code>#run the code
    #in this cell
        #away
</code></pre>

<p>The "cell" here may connote a jail cell, but more practically it describes a Python Notebook cell. Python Notebooks are a common way to experiment with Python, and the samples of output and the poem's culminating error message are typographically consistent with with what one would see while running this code in a notebook.</p>

<p>Montfort's program runs one permutation and prints the output: 120 variations on the five vowels arranged from 'AEIOU' to 'UOIEA' in 8 tidy, monospaced columns.</p>

<p>Bertram's program runs three times, and whereas Montfort's final line of Python 2 code prints the permutated combinations as a string (<code>print ''.join(list(permutations('AEIOU')))</code>), Bertram's Python 3 simply prints the list as it is represented in Python's memory. The first iteration permutes a single-character:</p>

<pre><code>print (list(permutations(&quot;I&quot;)))

['I']
</code></pre>

<p>In addition to this invitation to experience the practical implementation of the program, this different in printing the yield of the <code>permutations</code> function pulls us toward the subjective point-of-view of the Python runtime that experiences the code, and the chaotic typography of the output -- in contrast to Montfort's neat rows and columns -- performs the messy complications of computation that will eventually culminate in the runtime's demise.</p>

<p>There is one more subtle variation between Montfort and Bertram's code in the final line of the constructor. As it iterates through the <code>elements</code> list (a string of text characters, in this case) the newly-permutated line yields with <code>+ result[i:]</code> for Montfort or <code>+ result</code> for Bertram.</p>

<p>The functional difference is that Montfort's line restores to the target string only those parts of the input string that come after the character operating for the current iteration. The <code>[i:]</code> slice captures only those elements after <code>i</code>. Bertram's version retains and concatenates the entire working result, so the practical difference is that while Bertram's code will generate the same number of permutations, the strings it generates gradually become longer. The last element in the <code>permutations</code> of the string "can't" is <code>&quot;t'nact'nat'nt't&quot;</code>. I see this introducing a measure of inexhaustibility. Whereas the 120 permutations of "AEIOU" are a complete and homogenous set, <code>permutations(&quot;can't&quot;)</code> is asymmetrical and growing. The articulation of <code>print (list(permutations(&quot;breathe&quot;)))</code> runs past the right and bottom edges of the page.</p>

<p>The asymmetry culminates finally and dramatically with the full phrase "I can't breathe". Bertram's code concludes with the printout out of a Python MemoryError because the number of possible combinations of the 15 letters in that phrase (1,307,674,368,000) exceeds the available memory on the computer hosting the Python runtime, and like the 15 seconds that Officer Pantaleo held Eric Garner in a chokehold, those 15 characters result in the death of the Python Notebook or the computer hosting it.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/v9/7x3jz5l5v0ma.png" alt="&quot;Your session crashed after using all available RAM. View runtime logs." title="" /></p>

<p>I attempted to run Bertram's code two different ways: first in a Google-hosted Colab Notebook and later in a Jupyter Notebook running on my laptop. The Colab Notebook ran for some time with the RAM usage indicator creeping slowly to the right and becoming first green, then yellow, and finally orange before the runtime crashed and disconnected.</p>

<p>On my Macbook Pro, the results were similar, but as Python continued to take up more and more RAM, my computer gradually stopped working. The cursor slowed down, the trackpad clicked more slowly, and keyboard shortcuts stopped working. I couldn't take a screenshot, so I had to use another device -- my phone -- to capture the final moments before I resorted to a hard reboot and power cycle.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/9m/yao0a8udlay3.png" alt="&quot;Memory Pressure&quot; showing RAM usage on my computer." title="" /></p>

<p>It seems trivial or maudlin to compare a computer running out of memory to the tragedy of Eric Garner's asphyxiation and death, but the way the computer's memory usage creeped steadily upward conveyed a vivid anxiety and sense of panic in a way that was hauntingly effective. This poem is directly addressing the physical environment of computing in a manner reminiscent to Montfort's poem "Round", or Sam Lavigne's parodic "Slow Hot Computer" project that "makes your computer run slow, and hot, so you can be less productive" by running "processor-intensive calculations" in a web browser.</p>

<p>This kind of metaleptical irruption of attention -- what Terry Harpold has called "recapture" -- is typically accomplished in the service of play, both in the satiric sense of Lavigne's playfully critical projects and, for Harpold, in both the literal sense of playing videogames and the semiotic sense of expressive freedom within constraints. In Montfort's examples, recapture moderates the conflicts of entanglement with technical limitations are expressed through the terms of the gameworld, as when a text-based game attempts to parse an unknown word of user input and it replies "I didn't quite understand that" instead of reporting an error code or just crashing. Recapture is fundamental operation of videogame, which means that "recapture happens during play, in the complex digressions and feedback loops that are activated in actual play."</p>

<p>Bertram's works withe same entanglement of technical process and expressive semiotics, but poetry is not a videogame, and in this case, the poem denies its reader the recapture of memory, challenging us instead to bear witness to the trauma it represents.</p>

<p>As Wendy Hui Kyong Chun has discussed, computer memory is an "enduring ephemeral," always-already conflating memory with storage and, through metaphors and pretenses of permanence. She notes that the instability of this term, memory, follows the volatility of RAM, which is "based on flip-flop circuits and transistors and capacitors" and which require a steady electrical current" (169). Like human memory, software "memory is not a static but rather an active process. A memory must be held in order to keep it from moving" (167). Bertram's software presents the volatility of memory as the entanglement of poetic representation, police brutality, and technical limitation, and by setting it up to fail, Bertram invites us to reenact the trauma of that brutality and interpret its technical and political consequences.</p>

<p>When Bertram disrupts the symmetry of Montfort's slices (<code>result[:i]</code> and <code>result[i:]</code> becomes <code>result[:i]</code> and <code>result</code> so that "ehtaerb" potentially becomes the drawn-out, Joycean susurration "ehtaerbehtaerehtaeehtaehtehe", that is, <code>print(list(permutations(&quot;breathe&quot;))[-1])</code>), but both versions of the generator choke on Eric Garner's three last words. Memory fails, but the poem preserves its failure even as its overflow suggests a world uncontemplated by code. This overflow is not infinite -- hinting that someday, when it becomes possible to run this program with the multiple terrabytes of RAM necessary to compute and convey one trillion three-hundred seven billion six-hundred seventy-four million three-hundred sixty-eight thousand lines, the program will complete, but until then we are compelled to follow Bertram's invitation to bear witness and</p>

<pre><code>#return
    #this articulation
#the exhaustion
    #we can't stop hearing
</code></pre>

<h2>A NEW SERMON ON THE WARPLAND</h2>

<p>Like "three_last_words" and "Counternarratives," "A NEW SERMON ON THE WARPLAND: a poem by algorithm" is a work with a genealogy, and Bertram directs us to the source codes that ground it. This is another poem where Bertram gives credit to an example by Nick Montfort, but his code is a straightforward implementation of Alison Knowles' "A House of Dust," so Knowles is the more appropriate counterpoint for Bertram's work. More significantly, Bertram acknowledges "that some words and phrases ... are taken directly from Gwendolyn Brooks' corpus" in her notes, so understanding those origins allows these phrases to act hypertextually as a bridge into Brooks' poems. Bertram encourages us to explore that bridge by recommending Brooks' 1987 collection <em>Blacks</em>, and specifically points to "The Sermon on the Warpland" and <em>In the Mecca</em> as especially important sources. ("Boy Breaking Glass" and "THE WALL" also seem to be the sources for several phrases.)</p>

<p>Alison Knowles and James Tenney produced "A House of Dust" in 1968, the same year that Gwendolyn Brooks published <em>In the Mecca</em>. The source code for "House of Dust" is not publicly available, but its function is easy to deduce by examining the output published in three different venues. Knowles created the structure and four lists of words and phrases, and Tenney wrote those into FORTRAN code that creates quatrains by selecting and printing one item from each list, indenting each line a few spaces before returning to left justification as each new quatrain begins.</p>

<pre><code>A HOUSE OF ROOTS
    AMONG HIGH MOUNTAINS
        USING NATURAL LIGHT
            INHABITED BY VARIOUS BIRDS AND FISHES
A HOUSE OF WOOD
    BY A RIVER
        USING ALL AVAILABLE LIGHTING
            INHABITED BY HORSES AND BIRDS
A HOUSE OF DISCARDED CLOTHING
    UNDERWATER
        USING ELECTRICITY
            INHABITED BY FRENCH AND GERMAN SPEAKING PEOPLE
</code></pre>

<p>When I created a simulation of this poem in Javascript, I named these lists <code>materials</code>, <code>places</code>, <code>lights</code> and <code>inhabitants</code>. Montfort used the names <code>material</code>, <code>location</code>, <code>light_source</code> and <code>inhabitants</code>.</p>

<p>Bertram doesn't share her code in <em>Travesty Generator</em>, but observing its patterns reveals it to have a similar structure of lists randomly sampled. Also, two earlier versions of Bertram's "A NEW SERMON ON THE WARPLAND" are available online, one in Javascript (<a href="https://ruby-buffet.glitch.me" rel="nofollow">https://ruby-buffet.glitch.me</a>) and another in Python 2 (<a href="https://www.lybetc.tech/new-sermon-code" rel="nofollow">https://www.lybetc.tech/new-sermon-code</a>). In the Javascript version, each list simply bears a number (<code>one</code>,<code>two</code>, etc.), but the Python 2 version assigns names that signpost the function of each list. There are differences between the source code shared on Bertram's website and the code that created the poem published in <em>Travesty Generator</em>, but the <em>five</em> names suggest their content and reveal Bertram's primary departure from Knowles: <code>materials</code>, <code>locations</code>, <code>verb</code>, <code>means</code>, and <code>outcome</code>.</p>

<pre><code>A NATION OF GRIEF
               IN THE CUT
    SUMMONING
                    ANY MEANS NECESSARY
TO REFUSE ERASURE BY ALGORITHM
A NATION OF OLD DISPOSSESSIONS
               STILL FIGHTING
    CONJURING
                    ANY MEANS NECESSARY
TO REVISE ERASURE BY ALGORITHM
</code></pre>

<p>Comparing "House of Dust" with "NEW SERMON" reveals more differences than the addition of a fifth line. Knowles' locations are diverse but more stable -- "BY THE SEA", "IN MICHIGAN", "IN A HOT CLIMATE", "ON AN ISLAND","IN SOUTHERN FRANCE","AMONG OTHER HOUSE" -- while Bertram's are active, violent, or disrupted, and some are not conventionally "locations" but moreso describe liminal states of being:</p>

<blockquote><div>
  <p>...IN THE CUT... <br />
    ...STILL FIGHTING...<br />
    ...IN FRONT OF A WINDOW ABOUT TO BE BROKEN...<br />
    ...IN TRANSLATION...<br />
    ...BETWEEN SCYLLA AND CHARYBDIS...<br />
    ...IN THE SHIP'S HOLD...</p>
</div></blockquote>

<p>Instead of a house, Bertram addresses her sermon to a "NATION". Allusions to the slave trade are perhaps most striking in comparing the subtle differences in phrases between Knowles' "ON THE SEA" and Bertram's "ON SHIPS", but the shifts in Bertram's poem is much more than a inversion of Knowles'. While "A House of Dust" dwells, a NEW SERMON moves, acts, and resists. The <code>verbs</code> and <code>means</code> lists propel each cinquain through the same <code>means</code> -- "ANY MEANS NECESSARY" -- to the same <code>outcome</code>: <code>TO REFUSE ERASURE BY THE ALGORITHM</code>.</p>

<p>The earlier Python 2 version includes multiple possible outcomes, but the verbs list is somewhat shorter.  Because the printed version of the poem includes the same outcome in each cinquain, it is reasonable to infer that its source code is closer to the Javascript version where list <code>five</code> only contains one element, <code>to refuse erasure by the algorithm</code>. The <code>means</code> list works the same way, demonstrating that the only option is Malcom X's ANY MEANS NECESSARY.</p>

<p>For both of these one-choice lists, the program is still selecting that choice as the result of a process. The Python 2 draft uses the common <code>random.choice()</code> function, and the Javascript version takes a custom function with a comment remarking on its conventionality:</p>

<pre><code>// This is a very common randomizing function.
// It takes a list (array) and returns one at random.
function select_random(x){
    y = x[Math.floor(Math.random()*x.length)];
    return y;
}
</code></pre>

<p>The fact that this program is making a choice with no freedom plays into the slavery imagery within the poem, but revisiting "A House of Dust" opens another way of understanding the significance of this choice without a choice.</p>

<p>Benjamin Buchloh argues that Knowle's project in creating "House" was to find a way to deconstruct the "prison house of language". Noting the irony of an avante-garde artist like Knowles using a house, that most conventional vehicle for subject formation, as her central figure, Buchloh contends that the aleatory construction method of the poem demonstrates the infinite fluidity of the process of subject formation.</p>

<p>Channeling Nietzsche, Buchloh goes on to observe that the constructedness of "House of Dust" resists the subject's being at "home" in language. "Knowles's <em>The House of Dust</em> conceives of the process of subject formation as a perpetual process of construction and undoing, precisely to prevent it from becoming an inhabitant of the prisonhouse of language, a merely substitutional system of fraudulent and agressive convictions...the formation of of the subject at this point in history has become a more complex and, by necessity, a more open process, since the subject's intersections with language...are certainly no longer the primary ... foundations". Buchloh's "convictions" are a play on words, a synonym for "belief" in the mode of the metaphoric correctional system. But it also opens up another angle on "NEW SERMON," which is filled with punishment and captivity but conspicuously without conviction.</p>

<p>Although the Javascript version of the poem does include "of parolees" and "of prisoners" as possible <code>materials</code>, possibly drawn from Brooks' "The Wall", the printed poem's <code>materials</code> and <code>locations</code> invoke punishment without the framework of judicial justification:</p>

<blockquote><div>
  <p>...A NATION OF SPECIFIC CHAINS...<br />
    ...IN THE SHIP'S HOLD...<br />
    ...A NATION OF MEDGAR EVERS...<br />
    ...IN A STRING-DRAWN BAG...</p>
</div></blockquote>

<p>In this way, Bertram's poem comes back to the prison house of language that Knowles' is playfully resisting. Captivity and imprisonment are not just metonymic critiques for the post-structuralist decentering of lexical epistemology; instead, the prison house of NEW SERMON is the literal kidnapping, enslavement, and genocide of Africans whose exploitation built the foundations of this nation.</p>

<p>Finally, by naming one of the lists <code>verbs</code>, Bertram follows a schema one often finds in generative works that use context-free grammar: patterns or templates where words are given a syntactical place based on their part of speech. In NEW SERMON, the <code>verbs</code> list does the most work to take the poem away from its origins in "House of Dust". The seven <code>verbs</code> that appear in the 22 printed cinquains all suggest movement with resistance or a sense of bring something out from below:</p>

<blockquote><div>
  <p>DIGGING UP<br />
    SUMMONING<br />
    CONJURING<br />
    DIVINING<br />
    UNEARTHING<br />
    STRIKING MATCHES AGAINST<br />
    HOLLERING DOWN</p>
</div></blockquote>

<p>Each of these verbs immediately precedes "ANY MEANS NECESSARY". So, by omitting the preposition "by" from Malcom X's well-known phrase, the call to action in the poem asks its reader to dig up, to unearth, strike matches against their own <code>means</code> of refusing erasure.</p>

<p>In an appendix on the book, Bertram quotes Harryette Mullen's essay "Imagining the Unimagined Reader," "When I read words never meant for me, anyone like me ... then I feel simultaneously my exclusion and my inclusion as a literate black women, the unimagined reader of the text." Bertram likewise considers herself an "unimagined coder."</p>

<blockquote><div>
  <p>I use codes and algorithms in an attempt to create work that reconfigures and challenges oppressive narratives for Black people and to imagine new ones. I consider this an intervention into a set of literary practices that have historically excluded women and minorities.</p>
</div></blockquote>

<p>For each of the works I have analyzed here and for many others of 10 poems in <em>Travesty Generator</em>, Bertram uses the generators of computer-generated poetry to critique, resist, and replace narratives of oppression and to make explicit and specific what is elsewhere algorithmically insidious and ambivalent.</p>

<p>Lillian-Yvonne Bertram's <em>Travesty Generator</em> is a challenging, haunting, and important achievement of code poetry.</p>
]]>
        </description>
    </item>
    <item>
        <title>Week 3: Feminist AI (Main Thread)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/87/week-3-feminist-ai-main-thread</link>
        <pubDate>Mon, 03 Feb 2020 17:48:43 +0000</pubDate>
        <category>2020 Week 3: Feminist AI</category>
        <dc:creator>Christine.Meinders</dc:creator>
        <guid isPermaLink="false">87@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>by Christine Meinders, Jana Thompson, Sarah Ciston, Catherine Griffiths</p>

<p><strong>Feminist Legacy and Theory</strong><br />
As long as there has been code there have been feminist approaches to coding and pattern finding---such as the first<a rel="nofollow" href="https://twobithistory.org/2018/08/18/ada-lovelace-note-g.html">  complex program</a> which was created by Ada Lovelace in the 1840s, as well as<a rel="nofollow" href="https://www.atlasobscura.com/articles/knitting-spies-wwi-wwii/">  the use of knitting for encoding secrets during World War II</a>, often hidden in plain sight and overlooked for its perceived lack of value.</p>

<p>As artificial intelligence developed in the latter half of the twentieth century, most of its theorists and developers were overwhelmingly white and male. The roots of Feminist AI can be traced to contemporary theorists like British academics Alison Adam and <a rel="nofollow" href="https://psycnet.apa.org/record/1996-97938-005">Lucy Suchman</a>. In Alison Adam's <a rel="nofollow" href="https://www.routledge.com/Artificial-Knowing-Gender-and-the-Thinking-Machine-1st-Edition/Adam/p/book/9780203005057">Artificial Knowing</a>, she critiques traditional AI as symbolic and connectionist, both of which fail to address embodiment in the production of knowledge. Referencing <a rel="nofollow" href="https://www.taylorfrancis.com/books/9781315003221">Tong</a> (1994) and <a rel="nofollow" href="https://www.psupress.org/books/titles/0-271-00802-4.html">Wajcman</a> (1991), Adam argues that technology is inherently social, political, and cultural in its usage and production and that AI research can and should be informed by feminist theories such as liberal feminism, eco-feminism, postmodern feminism and standpoint theory. Additional Feminist theoretical approaches include participatory (<a rel="nofollow" href="https://dl.acm.org/doi/10.1145/1978942.1979041">BardzelI</a>), embodied (<a rel="nofollow" href="https://www.rowmaninternational.com/book/little_vast_rooms_of_undoing/3-156-5577c24f-e725-498e-8d26-ad80990d7a3b">Blumenthal</a>), implementation into practice (<a rel="nofollow" href="https://www.hup.harvard.edu/catalog.php?isbn=9780674728943">McPherson</a>), and design as research (<a rel="nofollow" href="https://mitpress.mit.edu/books/design-research">Burdick</a>). These approaches examine the mutable relationships of form, making, theory, and community.</p>

<p><strong>Feminist Practices and Projects</strong><br />
Building on earlier work, new critical approaches and projects have emerged in recent years, including volumes on racism and feminism such as Safiya Umoja Noble's Algorithms of Oppression, Cathy O'Neil's <a rel="nofollow" href="https://weaponsofmathdestructionbook.com/">Weapons of Math Destruction</a>, Joy Buolamwini's <a rel="nofollow" href="https://www.ajlunited.org/">Algorithmic Justice League </a>and Catherine D'Ignazio and Lauren F. Klein's <a rel="nofollow" href="https://mitpress.mit.edu/books/data-feminism">Data Feminism</a>. Additional feminist projects which explore the role of the body in knowledge production, critical prototyping, and critiques of science and technology include Ursula Damm's generative video project<a rel="nofollow" href="http://ursuladamm.de/membrane-2019/">  Membrane</a>,<a rel="nofollow" href="http://www.wekinator.org/">  Wekinator</a> by Rebecca Fiebrink, design approaches from<a rel="nofollow" href="https://feministinternet.com/"> Feminist Internet.com</a>,<a rel="nofollow" href="https://feministinternet.org/">  Feminist Internet.org</a>,<a rel="nofollow" href="https://lauren-mccarthy.com/LAUREN">  LAUREN</a> by Lauren McCarthy, Anne Burdick's digital humanities design fiction<a rel="nofollow" href="http://micromegameta.net/trina/">  Trina,</a><a rel="nofollow" href="https://gendersec.tacticaltech.org/wiki/index.php/Main_Page">  Gender and Tech resources project</a> by Tactical Tech,<a rel="nofollow" href="https://adanewmedia.org/2019/02/issue15-ciston/">  ladymouth</a> by Sarah Ciston, Catherine Grffiths'<a rel="nofollow" href="https://isohale.com/VISUALIZING-ALGORITHMS">  Visualizing Algorithms</a>, and Caroline Sinders' work on the<a rel="nofollow" href="https://carolinesinders.com/feminist-data-set"> Feminist Data Collection</a>, which details a path for building data collections and ontologies in a feminist reference and framework.</p>

<p>The organization Feminist.AI (to be distinguished from the conceptual approach Feminist AI) is a collective based across three cities (LA, SF, and Holdenville, OK) which strives to redefine AI from its current development in private companies and academic settings to community and socially-driven futures. Feminist.AI is developing a project called Feminist Search that explores many of the issues and approaches of Feminist AI practices through community-driven research and prototyping. Feminist Search is used to actively highlight the work of feminist theorist Dr. Safiya Umboja Noble, and her book <a rel="nofollow" href="https://nyupress.org/9781479837243/algorithms-of-oppression/">Algorithms of Oppression</a>. </p>

<p><strong>Feminist.AI Project: Feminist Search (Searching for Ourselves) </strong><br />
Feminist.AI emphasizes and employs critical prototyping, participatory focused approaches (BardzelI), acknowledging creators, de-centering the human (Adam, Hayles, Braidotti), and viewing embodiment as beyond the enfleshed, as a body-self---living and indefinite (Blumenthal). Feminist.AI is an explicitly feminist practice and this value appears in our projects, including the recent offering Feminist Search, which involved co-creating a Feminist Search Engine. Sarah Ciston has <a rel="nofollow" href="http://2019.xcoax.org/pdf/xCoAx2019-Ciston.pdf">written</a> elsewhere in more detail about bringing intersectional methodologies to artificial intelligence.</p>

<p>Feminist Search addresses this multi-faceted approach to search and offers visual entry points as a starting place. It requires participatory engagement and critical prototyping. Feminist Search also engages the challenges of working within a binary, asking how that construct impacts the weighting and utilization of specific models, as well as how the interface design can highlight data bias or community contributors.</p>

<p>Search is one of the most commonly-used algorithms in the world and it is dominated today by several large private corporations, most notably Google. Google's search algorithm is driven by a combination of usage and ad revenue. The first Google search algorithm, PageRank, was used to measure and prioritize websites ranked according to a number of factors, and a more recent explanation is detailed in the video<a rel="nofollow" href="https://www.youtube.com/watch?v=0eKVizvYSUQ"> "How Google Search Works (in 5 minutes)."</a>  To summarize, a search engine is comprised of a database (which can include things like images, webpages, videos, pdf's), and algorithms that interact with information on the web (such as text, metatags, links).  When searching, software is used to enter in a text based query and results are returned via text, voice or images. Search engines use web crawlers (spiders, spiderbots) to collect information about pages. These crawlers summarize links, tags, metatags and share information with the search engine. These "spiders" crawl across these pages to do several things---like find new content, index information, and rank. There is no human intervention---these algorithms are deployed in real time to gather information.</p>

<p>While these explanations clarify the process somewhat for the non-expert, they do not address the problematic features such as those covered by Safiya Umoja Noble, beginning with her 2012 article<a rel="nofollow" href="https://safiyaunoble.files.wordpress.com/2012/03/54_search_engines.pdf"> Missed Connections: What Search Engines Say About Women</a>. In both this and her 2018 book, Algorithms of Oppression, Noble discusses the troubling intersection of search results and Black bodies, including returning a page of primarily pornographic pages when entering the term "black girls" and on results for searches for professional hairstyles returning pictures of primarily white women. Additional problems with web search involve indexing algorithms and filter bubbles. Specifically, information is linked, indexed, and personalized using factors and decisions that are not transparent. Professor Noble highlights the lack of review process for determining what is hyperlinked (Noble 41). Unwanted bias can also occur with filter bubbles which can serve up narrow information in personalized search.</p>

<p>Starting with a visual search prototype that uses community sourced images, Feminist.AI will build a larger visual search engine powered by community definitions and informed by library science and critical theory. With a belief in users as not only contributors, but also as owners of their experience and information, an editable, co-created search tool will be developed where users have control over access to their information and how it is used for development. Using this as inspiration, the Feminist.AI community proposes to create an alternative to private search engines with the working title Feminist Search.</p>

<p>Feminist Search seeks to add transparency to the search process and promote education about factors that determine how search results are created. The project creates multiple entry points for community members to learn about how information is classified, trained and accessed, making search more understandable and accessible. In our next post, we will go further into details of the <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/discussion/88/week-3-feminist-search#latest">Feminist Search</a> project.</p>

<p><strong>Critical Questions:</strong><br />
1 - How do engaging feminist principles and practices around embodiment, community, and critical prototyping shift how code might be read or written? How do they shift how you understand or engage AI more broadly?</p>

<p>2 - Historically, the contributions of female-identified persons has often been overlooked in the main narratives of events, as seen in the stories of one of humanity's most famous scientific achievements - t<a rel="nofollow" href="http://wg18.criticalcodestudies.com/index.php?p=/discussion/18/week-1-colossus-and-luminary-the-apollo-11-guidance-computer-agc-code#latest%22">he Moon landing in July 1969</a>, or in the algorithmic processes of weaving or knitting. How can we reframe and revaluate traditionally "female" practices in light of today's emphasis on STEM education and create feminist spaces for both learning and developing coding practices?</p>

<p>3 - Can we imagine different sensory approaches for querying information? Currently, we use computers, with typing, voice search, and touch on screens. Could we simply improve our screen interfaces to incorporate new visual and interactive models of knowledge? How might we synthesize human and natural environments through search? How can we incorporate culturally specific ways of exploring knowledge through artifacts?</p>

<p><strong>Contribute to this research!</strong><br />
We invite you to contribute to this research. We are currently seeking data donations for our Feminist Search prototype. You may donate your data here: <a rel="nofollow" href="https://aidesigntool.com/feminist-search">https://aidesigntool.com/feminist-search</a></p>

<p>Thank You CCSWG 2020 community: Mark Marino, Jeremy Douglass, Zach Mann.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: internationalization of BASH scripts</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/90/code-critique-internationalization-of-bash-scripts</link>
        <pubDate>Tue, 04 Feb 2020 14:47:08 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>dcuartielles</dc:creator>
        <guid isPermaLink="false">90@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Prelude</strong><br />
Working from a command line interface (CLI) is experiencing a comeback ... over the last 20 years as a teacher in SW and HW for designers and artists, I have experienced an evolution of the tools that seems to be bringing SW creators (even the occassional developer) back to CLI and away from the UI.</p>

<p><strong>The story</strong><br />
In late 2015 I wanted to contribute to the work done in the hacking of FPGAs, in particular to project IceStorm. Back then I was in the middle of writing my PhD and I needed a break for a couple of days after getting one of my chapters rejected for the third time. Contributing to an open source project felt like a great way to recharge batteries.</p>

<p>For those not informed about the development of those tools. Field programmable gate arrays (FPGAs) are chips with no pre-loaded computing architecture. Microcontrollers, for example, come with a pre-loaded CPU, programs can be written on top of the CPUs commands. FPGAs allow to create your own CPUs. FPGA vendors' business consist in selling not just the chips, but also the programming tools (SW + HW), and development kits. Therefore, opening up any part of the process (as in <em>open sourcing</em>) is considered bad for business, since there is some money that will be made by someone else instead of the vendors.</p>

<p>A couple of years ago, and thanks to the effort of Claire Wolf (creator of IceStorm), several tools emerged that allowed creating code for a specific brand of FPGAs. Reverse engineering the bitcode to the FPGAs they opened for the possibility of people writing their own IDEs to create their own computing architectures.</p>

<p>I decided to contribute to this project because I knew one of the main contributors to the examples around IceStorm and creator of the Alhambra board, Juan Gonzalez Gomez, aka Obijuan. I looked at making the installation of the software and Obijuan's examples easier for those not speaking English, by creating the following repository:</p>

<p><a href="https://github.com/dcuartielles/open-fpga-install/" rel="nofollow">https://github.com/dcuartielles/open-fpga-install/</a></p>

<p>In order to make this happen, I used the following article from 2010 on how to localize bash scripts:</p>

<p><a href="https://www.linuxjournal.com/content/internationalizing-those-bash-scripts" rel="nofollow">https://www.linuxjournal.com/content/internationalizing-those-bash-scripts</a></p>

<p>The work done here was based on the idea that people should have an easy time installing from CLI and that having all of the messages in their own language should reduce the friction in that process. It took two years before I got a comment on how to improve the software (and I didn't notice until I started writing this post, 2 years later).</p>

<p>The mechanism for doing the BASH translation is done through calls to</p>

<p><code>i18n_display &quot;your text string here&quot;</code></p>

<p>The text string will be translated -on the fly- by taking it from the localization files under the <em>translations</em> subfolder.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/7i/bx1qmq7szz02.png" width="366" alt="image" /></p>

<p>The structure of those translation files looks as follows:</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/fz/asc3zstfb625.png" width="425" alt="image" /></p>

<p>There you can see how <code>msgid</code> indicates the identifier to the string to be translated, while <code>msgstr</code> is the string in the translation language.</p>

<p><strong>The questions</strong></p>

<p>Years after having made this work, and despite its little success, I still wonder about the pedagogical value of prompting people about what is that their installation scripts are doing when installing things. If I create a tool and want to deploy it, I could write an article on my blog and explain the step by step operations needed to install all of the dependencies needed, or I could write a good BASH script that could be taken over others and translated to multiple languages.</p>

<ul>
<li>Do you feel, like I do, that CLI is coming back and that it is not that crazy to make the whole installation as a script, so that the actions and the documentation can be put in a format where it is easier to contribute to?</li>
<li>Which are the limitations offered by the sharing interface (Github in this case) towards other communites, how would a translation process look like?</li>
<li>Should it be workshops with potential community participants?</li>
<li>Would you, as a user of one of BASH scripts, find useful to understand what happens when you call the different actions? Or would you prefer a non-running environment (like a blog) where to read about it instead?</li>
<li>Have you ever installed a series of packages from CLI? How was your experience?</li>
</ul>

<hr />

<p><strong>Recommended readings</strong></p>

<p><a rel="nofollow" href="http://project.cyberpunk.ru/idb/in_the_beginning_was_the_command_line.html" title="In the beginning there was the command line">In the beginning there was the command line</a> by Neal Stephenson</p>

<p>Project IceStorm: <a href="http://www.clifford.at/icestorm/" rel="nofollow">http://www.clifford.at/icestorm/</a></p>

<p>Clifford on programming style: <a href="http://www.clifford.at/style.html" rel="nofollow">http://www.clifford.at/style.html</a> (could be enough for another post)</p>

<hr />
]]>
        </description>
    </item>
    <item>
        <title>CCS Bibliography</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/52/ccs-bibliography</link>
        <pubDate>Sat, 18 Jan 2020 19:12:12 +0000</pubDate>
        <category>2020 General</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">52@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Add new titles for our Critical Code Studies Bibliography or add them directly to this <a rel="nofollow" href="https://docs.google.com/document/d/1cd-4qmwRHXW0BhgOddxKotBGVI97nS6zwgo6hAQot7A/edit?usp=sharing" title="Google Doc">Google Doc</a>.</p>
]]>
        </description>
    </item>
    <item>
        <title>Distant Writing: Code Critiques from NaNoGenMo and NNNGM</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/85/distant-writing-code-critiques-from-nanogenmo-and-nnngm</link>
        <pubDate>Mon, 03 Feb 2020 12:03:56 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Leonardo.Flores</dc:creator>
        <guid isPermaLink="false">85@/index.php?p=/discussions</guid>
        <description><![CDATA[<h1>Distant Writing</h1>

<p>How does a poet end up thinking in terms of algorithms, programming languages, and datasets?</p>

<p>I’m interested in exploring the work of writers of electronic literature who, instead of writing sequences of words directly, create a computer program or modify an existing one to generate their intended texts.</p>

<p>The practice of creating and repurposing “engines” encourage the development of born-digital poetic forms, such as Nick Montfort’s poem, “Taroko Gorge” which has been remixed hundreds of times since its publication in early 2009.</p>

<p>My notion of distant writing inverts Franco Moretti’s concept of distant reading, which is in turn a counterpoint to the hegemonic concept of close reading, by applying it to writing. With close reading we pay careful attention to a (presumably carefully chosen) sequence of words (let’s call it close writing) to draw meaning and insight from it— much of what we’re doing here at the CCSWG. With distant reading, Moretti invites us to develop tools and methods to examine large literary corpora to find patterns and insights about literary texts and movements. Distant writing subverts the notions of subjectivity, intimacy, and proximity in the Romantic vision of a writer who painstakingly chooses and arranges words in intended sequences. Distant Writing is about writers who create and implement algorithms to produce texts that achieve their goals.</p>

<p>We can extend the metaphor by conceptualizing varying distances between the writer and their text depending on how much control over the inner workings of the textual generation process the writer has. Here are some case studies, from short-distance to long-distance writing.</p>

<h2>Short Distance Writing</h2>

<p>Nick Montfort is well known in this community as a writer of generative works. Most of his oeuvre consists of carefully crafted minimalist generative literature. The openness of the MIT License these works are published in, and the versatility of his programming has encouraged others to remix and repurpose his works, as has been the case with “<a rel="nofollow" href="https://nickm.com/poems/taroko_gorge.html" title="Taroko Gorge">Taroko Gorge</a>” (2009). For the code study, I want to present something more recent, his Nano-NaNoGenMo (NNNGM) novel <em>consequence</em> (2019). Here’s the code (in Perl) in its entirety:</p>

<p><code>perl -e 'sub n{(unpack&quot;(A4)*&quot;,&quot;backbodybookcasedoorfacefacthandheadhomelifenamepartplayroomsidetimeweekwordworkyear&quot;)[rand 21]}print&quot;consequence\nNick Montfort\n\na beginning&quot;;for(;$i&lt;12500;$i++){print&quot; &amp; so a &quot;.n;if(rand()&lt;.6){print n}}print&quot;.\n&quot;'</code></p>

<p>When you run that code in a terminal window, you get output like this.</p>

<blockquote><div>
  <p>consequence<br />
  Nick Montfort</p>
  
  <p>a beginning &amp; so a doorword &amp; so a door &amp; so a lifeweek &amp; so a bodyname &amp; so a handface &amp; so a liferoom &amp; so a nameplay &amp; so a handdoor &amp; so a time &amp; so a bookplay &amp; so a backcase &amp; so a nameplay &amp; so a caseweek &amp; so a name &amp; so a life &amp; so a casepart &amp; so a homeroom &amp; so a doorword &amp; so a book &amp; so a yeartime &amp; so a book &amp; so a namehome &amp; so a time &amp; so a hand &amp; so a lifefact &amp; so a doorpart &amp; so a work &amp; so a roomlife &amp; so a sideyear &amp; so a yearhome &amp; so a nameroom &amp; so a part &amp; so a roomfact &amp; so a fact &amp; so a handbody &amp; so a workhand &amp; so a timefact &amp; so a playwork &amp; so a homebody &amp; so a headbody &amp; so a homeback &amp; so a headplay &amp; so a bookwork &amp; so a time &amp; so a door &amp; so a partbody &amp; so a bodyhand &amp; so a home &amp; so a wordyear &amp; so a play &amp; so a room &amp; so a facehead &amp; so a head &amp; so a roomdoor &amp; so a hand &amp; so a word &amp; so a workside &amp; so a caseweek &amp; so a word &amp; so a case &amp; so a bodydoor &amp; so a face &amp; so a backwork &amp; so a fact &amp; so a timeface &amp; so a yearcase &amp; so a case &amp; so a factplay &amp; so a life &amp; so a namename &amp; so a time &amp; so a fact &amp; so a door &amp; so a part &amp; so a bodybody &amp; so a faceyear &amp; so a week &amp; so a face &amp; so a book &amp; so a face &amp; so a door &amp; so a hometime &amp; so a wordpart &amp; so a lifeyear &amp; so a weekyear &amp; so a casebody &amp; so a nameside &amp; so a back &amp; so a partdoor &amp; so a sidebook &amp; so a backpart &amp; so a weekbook &amp; so a part &amp; so a</p>
</div></blockquote>

<p>You can read the blog post about it <a rel="nofollow" href="https://nickm.com/post/2019/11/nano-nanogenmo-or-nnngm/" title="here">here</a>.</p>

<p>Some comments to get the conversation started:</p>

<ul>
<li>Part of the NNNGM constraint is to produce a 50,000 word novel (in the NaNoGenMo tradition) but with the added constraint of doing so with a program that is at most 256 characters.</li>
<li>Montfort is experienced with this 256 character constraint, and created a series of generative poems titled <a rel="nofollow" href="https://nickm.com/poems/ppg256.html" title="ppg256">ppg256</a> (2007-2012) where he developed the word compounding technique he uses here and in "<a rel="nofollow" href="http://collection.eliterature.org/3/work.html?work=sea-and-spar-between" title="Sea and Spar Between">Sea and Spar Between</a>" (2010).</li>
<li>By using exclusively 4-letter words, he was able to create a data set that could output common words and more poetically charged compound words. The constraint, which is very Oulipian, also a neat mechanism for code compression.</li>
<li>The title, <em>consequence</em>, gestures towards that minimal foundation for plot--events connected by causality-- which is established by the connectors "&amp; so a" in this novel. One thing leads to another in <em>consequence</em> all the way to its final period.</li>
</ul>

<p>As distant writing goes, this is at a metaphorically short distance because the whole work is produced from this minimalist code and self-contained data set. Nick can manipulate the code and data set until it produces the output that fits his creative vision. Let's take another look at a similar, but more distant kind of writing.</p>

<h2>Medium Distance Writing</h2>

<p><em>OB-DCK; or, THE (SELFLESS) WHALE</em> (2019) is also a NNNGM entry by Nick Montfort that transforms Herman Melville's <em>Moby Dick</em> into a version that removes all first person pronouns to remove the self, and the very narrator, from the novel.</p>

<p>Here's the complete code, though one must first <a rel="nofollow" href="https://www.gutenberg.org/files/2701/2701-0.txt" title="download the text from Project Gutenberg">download the text from Project Gutenberg</a> and put it in the same directory you will be running the perl script from in a terminal window:<br />
<code>perl -0pe 's/.*?K/***/s;s/MOBY(.)DI/OB$1D/g;s/D.*r/Nick Montfort/;s/E W/E (SELFLESS) W/g;s/\b(I ?|me|my|myself|am|us|we|our|ourselves)\b//gi;s/\r\n\r\n/</code>/g;s/\r\n/ /g;s/<code>/\n\n/g;s/ +/ /g;s/(“?) ([,.;:]?)/$1$2/g;s/\nEnd .*//s' 2701-0.txt</code></p>

<p>Here's some of the output it generates:</p>

<blockquote><div>
  <p>Epilogue</p>
  
  <p>“AND ONLY ESCAPED ALONE TO TELL THEE” Job.</p>
  
  <p>The drama’s done. Why then here does any one step forth?—Because one did survive the wreck.</p>
  
  <p>It so chanced, that after the Parsee’s disappearance, was he whom the Fates ordained to take the place of Ahab’s bowsman, when that bowsman assumed the vacant post; the same, who, when on the last day the three men were tossed from out of the rocking boat, was dropped astern. So, floating on the margin of the ensuing scene, and in full sight of it, when the halfspent suction of the sunk ship reached , was then, but slowly, drawn towards the closing vortex. When reached it, it had subsided to a creamy pool. Round and round, then, and ever contracting towards the button-like black bubble at the axis of that slowly wheeling circle, like another Ixion did revolve. Till, gaining that vital centre, the black bubble upward burst; and now, liberated by reason of its cunning spring, and, owing to its great buoyancy, rising with great force, the coffin life-buoy shot lengthwise from the sea, fell over, and floated by side. Buoyed up by that coffin, for almost one whole day and night, floated on a soft and dirgelike main. The unharming sharks, they glided by as if with padlocks on their mouths; the savage sea-hawks sailed with sheathed beaks. On the second day, a sail drew near, nearer, and picked up at last. It was the devious-cruising Rachel, that in her retracing search after her missing children, only found another orphan.</p>
</div></blockquote>

<p>It is discussed in the same blog post I cited earlier, available <a rel="nofollow" href="https://nickm.com/post/2019/11/nano-nanogenmo-or-nnngm/" title="here">here</a>.</p>

<p>Some comments:</p>

<ul>
<li>By detecting and eliminating all personal pronouns from a novel narrated in the first person, Montfort has almost completely deleted Ishmael from the narrative. Clearly, "one did survive the wreck," but who exactly? Who is this narrator that tells the story of these colorful characters, Ishmael, Ahab, Queequeg, and a white whale?</li>
<li>This kind of operation upon a novel hearkens back to Oulipian operations (such as the N+7 process, in which they would substitute nouns in a text with the seventh word that followed it in a dictionary to create a poetically distorted text), and is also firmly in the NaNoGenMo tradition, which draws heavily from <em>Moby Dick</em>.</li>
<li>This program only produces one output from a text, though it could be used on other texts.</li>
<li>The greater distance comes from the fact that it is built upon a text written by someone else. Montfort can modify the program to produce results that better achieve his artistic goals, but he can't change the main data set and still say it's <em>Moby Dick</em>.</li>
</ul>

<h2>Long Distance Writing</h2>

<p>With long distance writing, the author either has limited control over the engine or the data set. I will not offer a code sample for long distance writing because, in most cases, it is either unavailable or impractical, but here are some examples and thoughts.</p>

<ul>
<li>Two of my favorite Twitter bots, <a rel="nofollow" href="https://twitter.com/pentametron" title="@Pentametron">@Pentametron</a> by Ranjit Bhatnagar and <a rel="nofollow" href="https://twitter.com/HaikuD2" title="@HaikuD2">@HaikuD2</a> by John Burger, search through the Twitter stream for tweets that happen to be in iambic pentameter and rhyme before retweeting them together or that could be cut into the shape of a haiku, respectively. One could argue that Bhatnagar and Burger haven't really written anything, and have only created the programs to distill rhyming couplets and accidental haiku from Twitter, but that would feel somehow unfair to the wonderful texts their bots produce. Their intent, craft, and execution results in works that wouldn't have existed without their vision, and that constitutes authorship, as far as I'm concerned.</li>
<li>Bhatnagar's 2018 book <em><a rel="nofollow" href="http://counterpathpress.org/encomials-sonnets-from-pentametron-ranjit-bhatnagar" title="Encomials: Sonnets from Pentametron">Encomials: Sonnets from Pentametron</a></em> explores the concept further by using different formal constraints to produce more complex poetic structures drawn from the raw material detected by <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/profile/Pentametron">@Pentametron</a>. These feel less distant than his original bot, because we see Bhatnagar making more deliberate choices and refining his programming to produce output that more closely achieve his vision.</li>
<li>Another popular method consists of training a Markov chain generator, neural network, AI framework, or chatterbot with texts and then prompting them to produce output based on the probabilities they detect. This year's NaNoGenMo featured <a rel="nofollow" href="https://github.com/NaNoGenMo/2019/search?q=gpt-2&amp;type=Issues" title="several works">several works</a> that used <a rel="nofollow" href="https://github.com/openai/gpt-2" title="GPT-2">GPT-2</a>, an open AI framework. The authorial impulse is to train the frameworks, many of which operate as black boxes, to produce the kinds of output one desires.</li>
<li>An example of this is <em><a rel="nofollow" href="https://github.com/NaNoGenMo/2019/issues/18" title="The Orange Erotic Bible">The Orange Erotic Bible</a></em> (2019), an anonymous work generated by the GPT-2 framework trained on a corpus of erotic literature and the King James Bible to produce erotic texts in the biblical tradition. You can see the code, corpora, and generated novel (Bible?) in the Github issue. The distance between the author and the text produced is substantive-- they didn't write any of the source texts, and performed limited operations on the output. Yet the results are so hilariously NSFW that I understand why the author chose anonymity to put some additional distance between themselves and the work.</li>
<li><a rel="nofollow" href="https://twitter.com/eturner303/status/1223976313544773634" title="This tweet">This tweet</a> refers to a case of distant writing (of a bot powered character) that feels most removed from the authorial team (Google?) than all the previous cases. Here we have the distance of corporate authorship (Google's AI team) and a chatbot whose operations are hidden in a hardware and software black box. The only information that achieves escape velocity from this corporate black box is news of the effort, resources, and processing feats achieved.<br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/m8/4tpf32upcvcv.png" alt="" title="" /></li>
</ul>

<h2>Closing In on Distant Writing</h2>

<p>Now that I've introduced the concept of distance from one's writing and shared some examples, I invite commentary and critique: of the concept, the examples, and the code provided. I hope this generates some conversation!</p>
]]>
        </description>
    </item>
    <item>
        <title>FatFinger.JS</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/97/fatfinger-js</link>
        <pubDate>Sun, 09 Feb 2020 18:58:43 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Temkin</dc:creator>
        <guid isPermaLink="false">97@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Ordinarily, code with typos does not execute. A helpful IDE marks the misspelled keywords or variables with red-squigglies, or an interpreter reports the entire line as a syntax error. You are expected to fix it and rerun.</p>

<p>While human readers have a high tolerance for elision, for swapping of letters, or missing symbols, programming languages generally have no tolerance for this. The history of obfuscated code and of esoteric programming languages are breaks from clarity of presentation -- but the code itself is exacting and precise. Entries to the <a rel="nofollow" href="https://www.ioccc.org/">IOCCC, the International Obfuscated C Code Contest</a>, look random or scrambled. However, to actually run as C programs means that behind their seeming chaos is the same compulsive approach to code.</p>

<p>I developed FatFinger, a dialect of JavaScript, to challenge this approach. FatFinger allows misspellings and typos as valid code. To get an idea of how this looks, here is a 99 Bottles of Beer program in FatFinger:</p>

<pre><code>&lt;script type=&quot;text/javascript&quot; src=&quot;fatfinger.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javoscript&quot;&gt;
    var bottles;
    for (var counter = 99; counter &gt;= 1; counter = counter - 1) 
    {
        if (counter == 1) {
            botles = 'bottle';
        } else {
            bottles = 'bottles';
        }
        constole.log(counter+&quot; &quot;+ bottless +&quot; of ber on the wall.&quot;);
        if (countr &lt; 99) {
            conssole.lg(&quot;&quot;);
            consoles.logg(counter+&quot; &quot;+ botttles+&quot; o beer on the wall.&quot;);
        }
        conable.log(counter+&quot; &quot;+botles+&quot; of beer.&quot;);
        console.lo(&quot;Take one down.&quot;);
        console.log(&quot;Pass it arund.&quot;);
        ift (ount == 1) {
            console.log(&quot;No botles of beer on the wall.&quot;);
        }
    }
&lt;/script&gt;
</code></pre>

<p>The counter and bottles variables are both explicitly declared with <code>var</code>. FatFinger, unlike regular JS, requires explicit declaration because it will assume implicit variables are actually misspelled variables declared earlier.</p>

<p><code>bottles</code> is variously written as <code>botles</code>, <code>bottless</code>, <code>botttles</code>. Even built-in JavaScript objects like <code>console</code> can also be misspelled, here as <code>constole</code>, <code>connstole</code>, and <code>conable</code>. The sloppy work seeps into the strings themselves, so it is not printing "No more bottles of beer on the wall." but actually "No more botles".</p>

<p>To get this script to execute as FatFinger in the html page, we have to first include the fatfinger.js library, and then put our FatFingered code within a script tag with any misspelling of JavaScript (here "javoscript" on line 2).</p>

<p>Behind the scenes, of course, FatFinger needs to turn this into functioning JavaScript that will run in the browser. It does this by finding identifiers that it can't identify and comparing them to a list of everything in scope. It uses <a rel="nofollow" href="https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance">Damerau–Levenshtein distance</a> to find the closest match. This is the minimum number of operations (consisting of insertions, deletions or substitutions of a single character, or transposition of two adjacent characters) required to change one word into the other. So each unknown identifier is transformed into the one with the closest-matching name.</p>

<p>While this project had to be written in JavaScript -- the most chaotic of widely used languages -- it caused an issue in that building a list of what's in scope is not so easy. JS doesn't have a fully developed system of reflection -- the ability to read its own metadata and inspect itself -- that Java or C# does. In the <a rel="nofollow" href="https://github.com/rottytooth/FatFingerJS/blob/master/src/wordReplacer.js#L126">buildLocalIdentifiers method</a> we can see how this is done, with all the FIXMEs about scope issues. It begins with this comment:</p>

<pre><code>// FIXME: there no scope and it doesn't even know if a var has been declared yet or not.
// Perhaps capture line numbers where things are declared and use the tree (since at this stage we can generate one) to help with 
// scope? However, public/private is tricky in js and there are cases where you can refer to things that are not yet declared
</code></pre>

<p>For the moment, these are mostly settled with a warning that "FatFinger has a poor concept of scope, so if you're doing fancy OO stuff, ask yourself: is there a good reason I haven't made everything global??? If not, this might not be the right library / coding style for you."</p>
]]>
        </description>
    </item>
    <item>
        <title>Week 2: Cree#</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/71/week-2-cree</link>
        <pubDate>Mon, 27 Jan 2020 18:54:21 +0000</pubDate>
        <category>2020 Week 2: Indigenous Programming</category>
        <dc:creator>joncorbett</dc:creator>
        <guid isPermaLink="false">71@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/5f/3m7hl73f2qc3.jpg" alt="" title="" /><br />
A simple example of "Hello World" in the first iteration of Cree# with it's graphic output.</p>

<p>Programs in Cree# are told as stories, connecting with the Cree tradition; the graphical output can’t exist without the story that the code is telling. A Cree# program is also a multimedia story. In the above example, we have Raven (the Trickster), a character from Cree folklore who is as well known for his mischievousness as he is known for his role as a teacher and a guide. The program initializes when Raven flies on to the screen and lands on a tree and ends when the Raven flies away. But while sitting on the tree, Raven can perform a number of tasks. In the above example, the Raven says “Hello World” in Cree. But Raven can perform any number of activities, which occur randomly or are controlled through user interaction. It is in the tree-state that the actions of Raven can occur in any order, these activities are only dependant on the storyteller, as each storyteller that tells this story does so with slight modifications and changes in behaviours of Raven in order to emphasize a particular aspect of the story. The Cree# language favours this flexibility in the body of the story so that the generative and dynamic nature of the storyteller’s personality can be reflected in the code, the result is that though a similar (or same) story by different storytellers (i.e. programmers) will be noticeably different in their graphic output, even though they tell the same story.</p>

<p>For an example of what that looks like, here is a longer program in Cree#:</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/01/4ub21a70cnd7.png" alt="" title="" /></p>

<pre><code>ᒥᔭᐦᑲᓯᑫ᙮
ᒪᒪᐁᐧᔭᐢ ᐃᐧᐦᐅᐃᐧᐣ ᐊᒐᑭᐯᐊᐧᓯᓇᐦᐃᑭᐧᐣ᙮ᑕᓂᓯ᙮
   ᐅᓯᐦᒋᑫᐤ ᑳᐦᑳᑭᐤ᙮
   ᐅᓯᐦᒋᑫᐤ ᒥᐢᑎᐠ᙮
▬
   ᑳᐦᑳᑭᐤ᙮ᐊᐧᐢᑭᑕᐢᑌᐤ᙮ᒥᐢᑎᐠ᙮
   ᐃ|| ᑲᐦᑲᑭᐘᐠ᙮ᐊᐧᐢᑭᑕᐢᑌᐤ᙮ᒥᐢᑎᐠ᙮
   | ᑳᐦᑳᑭᐤ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮
   ᑳᐦᑳᑭᐤ ᐃ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮
   ᑳᐦᑳᑭᐘᐠ᙮ᐅᔭᐱᐤ᙮
   ᑳᐦᑳᑭᐤ |᙮ᐃᑌᐧ᙮ᑕᓂᓯ ᒥᓯᐁᐧ ᐊᐢᑮᕀ᙮
   ᑳᐦᑳᑭᐤ᙮ᓇᓇᒫᐢᑲᒋᐤ᙮
   ᑳᐦᑳᑭᐤ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮
   ᒥᔭᐦᑲᓯᑫ ᒥᐢᑎᐠ᙮
◯
</code></pre>

<p>Because I am still working on the language there is no way to test the above code, so to provide a bit of background to Cree#: its intent is to capture story elements and animate them on the screen. Before writing the code, there must be a series of images or animations created first (like sprites or animated gifs). These are placed in applicable library folders that can then be used in the program by "Creating" them. The verbs used must also be predetermined and unique.<br />
Now as far as the language itself goes the only punctuation in Cree is the full stop "᙮" which is used here to separate statements. The two glyphs used for "start" and "stop" are a horizontal bar "▬", and a circle "◯" respectively. Or in other words "open the circuit" and "close the circuit".</p>

<p>Commands follow basic sentence construction of [noun].[verb], and in some cases [noun].[verb][parameter], and in most cases as long as the program reads in those patterns the order of the instructions is not necessarily relevant. The only exception is smudge, which must be the first line of the program, can be the last line, and can also receive parameter(s) so [smudge] and [smudge][parameter].</p>

<p><strong>Here is a quick run through of the example code:</strong></p>

<p>In this example I start the program with a smudge, then declare two "noun" variables "Raven" and "Tree", open/start the "animation" on line 5. In the first two lines I first add one Raven (ᑳᐦᑳᑭᐤ) to the tree , the next line changes the singular Raven to an array of 5 Ravens (ᐃ|| ᑳᐦᑳᑭᐘᐠ) - note the suffix change from "ᐤ" to "ᐘᐠ", this changes the singular to the plural. And now when I reference the Raven its as an array I can use both singular and plural forms:<br />
    <strong>Line 8:</strong>    1 Raven leaves flying<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#42; <em>because I don't indicate which Raven, one of the array is chosen at random and removed.</em><br />
    <strong>Line 9:</strong>    Raven <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%233&amp;Mode=like">#3</a> leaves flying.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#42; <em>Note that placing a number at the end of the array variable indicates the index - see the end note about Cree numbers</em><br />
    <strong>Line 10:</strong> using the variable in its plural form ᑳᐦᑳᑭᐘᐠ means apply the action to the entire set<br />
    <strong>Line 11:</strong> Raven <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%231&amp;Mode=like">#1</a> speaks "Hello Turtle Island"<br />
    <strong>Line 12:</strong> Raven shivers with cold<br />
    <strong>Line 13:</strong> ᑳᐦᑳᑭᐤ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮&nbsp;&nbsp;&nbsp;  <em>//Raven leaves flying</em><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#42; <em>this actually only removes 1 raven at random, to remove all I could smudge the singular ᑳᐦᑳᑭᐤ or all ᑳᐦᑳᑭᐘᐠ, or send them all flying ᑳᐦᑳᑭᐘᐠ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮</em><br />
    <strong>Line 14:</strong> smudge the tree<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#42; <em>the smudge function is used to "cleanse" or reset anything in the program. calling ᙮ᓯᐯᐧᐱᐦᐋᐤ᙮ without any variable will just wipe everything</em></p>

<p><strong>A note on numbers</strong> - the glyphs used for Cree numbers are based on "sticks" with the vertical bar or pipe being 1, 2 pipes is 2, 3 pipes is the same as the syllabic ᐃ, 4 is then ᐃ| - an so on  much like roman numerals. There are glyphs for indicating 5, 10, and 20, and higher numbers have differing ways of representing them. An extended example - in many Indigenous numbering systems (not just Cree) the representation of 5 is a hand, and 20 is a person or body, because we are made of 20 digits (10 fingers and toes).</p>

<p><strong>Cree is also a morphemic language</strong>, so as long as you know the rules for combining syllables your programming can also be a series of syllable commands strung together. For example there is a prefix "mista" (ᒥᐢᑕ) that can be added to a word to make it a larger version of itself, like ᒥᐢᑕᑳᐦᑳᑭᐤ would be Big Raven, in Cree# this is also a way of adding so - ᒥᐢᑕᑳᐦᑳᑭᐤ (literally big ravens) would actually be a way of increasing my array of 5 Ravens to 6 Ravens. Likewise the suffix "osis" (ᐅᓯᐢ) makes it smaller. ᑳᐦᑳᑭᐤᐅᓯᐢ would therefore remove 1 from the array. And though I have yet to see a need for it, combining the two is still a legal statement so “mista-kahkakiw-osis” or  ᒥᐢᑕᑳᐦᑳᑭᐤᐅᓯᐢ, is the same as saying Raven = Raven + 1 - 1.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: CryptoKitties</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/89/code-critique-cryptokitties</link>
        <pubDate>Tue, 04 Feb 2020 05:17:59 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>meredith.noelle</dc:creator>
        <guid isPermaLink="false">89@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Cryptokitties<br />
Author/s: Gerald Bauer, <a href="https://github.com/geraldb" rel="nofollow">https://github.com/geraldb</a><br />
Language/s: Solidity <br />
Year/s of development: 2018<br />
Software/hardware requirements (if applicable): Ethereum Network (can be a test network).</p>

<p>The last 10 years as seen many people question traditional monetary models. One of the results of this has been the rise, fall, and rise (and perhaps fall or statis), of various cryptocurrencies like bitcoin and ethereum.  Cryptokitties is an example of a smart contract. It is a particular kind of smart contract, a token. And it is a particular kind of token, a non-fungible token. So if a regular token is like a $1 bill (all $1 bills are the same), a non-fungible token is like a jewel or collectable. Each jewel is slightly different from another one.</p>

<p>CryptoKitties are representations of virtual kitties that are non-fungible tokens. Cryptokitties would be 'born' at random intervals with different attributes, and then could breed with one another to create new cryptokitties.  Cryptokitties became enormously popular with some being exchanged for 100,000s USD. It spawned the creation of a new Smart Contract Standard - ERC-721, and people working in this field.   There are a number of Solidity smart contracts that allow cryptokitties to work. You can see them all on <a rel="nofollow" href="https://github.com/cryptocopycats/awesome-cryptokitties/tree/master/contracts">github</a>. This code snippet is the base class of the CryptoKitty itself.</p>

<p>Some wide ranging questions about the code:<br />
1. What makes this code? If we take a legal contract and translates it into a smart contract. What does it gain or lose in becoming code (or a smart contract)? What happens when it become a subject of software studies in addition to legal studies? How is this different from say the a header file and the implementation, or a configuration file? Do they both have the same status as code?</p>

<ol start="2">
<li><p>The code includes very specific ideas about embodiment, biology, and genetics.  What is the impact of that on the community of coders and collectors and the kitties themselves. For example, what would it look like if we had Cryptokitties based on Haraway's notion of Kin (or even cyborgs).</p></li>
<li><p>This sort of program 'performs' in a different way than other programs in that it has (or generates) exchange value in the world. Is this relevant at all to our discussion software?  If we consider software to be 'performative' or a 'Speech Act' in a JL Austin way, are there different categories of acts for software? Is this a function of the software or of the compiler or platform?</p></li>
<li><p>Can we consider this program apart from the Ethereum platform? What is the relationship between this software and the network it runs on, can we consider it in isolation? Is this a similar question to ML and the training set of Data.</p></li>
<li><p>What cultural ideas are embedded here: a love of cats memes on the internet, KittyAccessControl, Matron, Sire, auctioning kitties in general, cooldown period (is this like a nuclear reactor)?</p></li>
<li><p>Money - but we have enough to talk about.</p></li>
</ol>

<pre><code>/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged.

contract KittyBase is KittyAccessControl {
    /*** EVENTS ***/

    /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously
    ///  includes any time a cat is created through the giveBirth method, but it is also called
    ///  when a new gen0 cat is created.
    event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes);

    /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten
    ///  ownership is assigned, including births.
    event Transfer(address from, address to, uint256 tokenId);

    /*** DATA TYPES ***/

    /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy
    ///  of this structure, so great care was taken to ensure that it fits neatly into
    ///  exactly two 256-bit words. Note that the order of the members in this structure
    ///  is important because of the byte-packing rules used by Ethereum.
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Kitty {
        // The Kitty's genetic code is packed into these 256-bits, the format is
        // sooper-sekret! A cat's genes never change.
        uint256 genes;

        // The timestamp from the block when this cat came into existence.
        uint64 birthTime;

        // The minimum timestamp after which this cat can engage in breeding
        // activities again. This same timestamp is used for the pregnancy
        // timer (for matrons) as well as the siring cooldown.
        uint64 cooldownEndBlock;

        // The ID of the parents of this kitty, set to 0 for gen0 cats.
        // Note that using 32-bit unsigned integers limits us to a &quot;mere&quot;
        // 4 billion cats. This number might seem small until you realize
        // that Ethereum currently has a limit of about 500 million
        // transactions per year! So, this definitely won't be a problem
        // for several years (even as Ethereum learns to scale).
        uint32 matronId;
        uint32 sireId;

        // Set to the ID of the sire cat for matrons that are pregnant,
        // zero otherwise. A non-zero value here is how we know a cat
        // is pregnant. Used to retrieve the genetic material for the new
        // kitten when the birth transpires.
        uint32 siringWithId;

        // Set to the index in the cooldown array (see below) that represents
        // the current cooldown duration for this Kitty. This starts at zero
        // for gen0 cats, and is initialized to floor(generation/2) for others.
        // Incremented by one for each successful breeding action, regardless
        // of whether this cat is acting as matron or sire.
        uint16 cooldownIndex;

        // The &quot;generation number&quot; of this cat. Cats minted by the CK contract
        // for sale are called &quot;gen0&quot; and have a generation number of 0. The
        // generation number of all other cats is the larger of the two generation
        // numbers of their parents, plus one.
        // (i.e. max(matron.generation, sire.generation) + 1)
        uint16 generation;
    }

    /*** CONSTANTS ***/

    /// @dev A lookup table indicating the cooldown duration after any successful
    ///  breeding action, called &quot;pregnancy time&quot; for matrons and &quot;siring cooldown&quot;
    ///  for sires. Designed such that the cooldown roughly doubles each time a cat
    ///  is bred, encouraging owners not to just keep breeding the same cat over
    ///  and over again. Caps out at one week (a cat can breed an unbounded number
    ///  of times, and the maximum cooldown is always seven days).
    uint32[14] public cooldowns = [
        uint32(1 minutes),
        uint32(2 minutes),
        uint32(5 minutes),
        uint32(10 minutes),
        uint32(30 minutes),
        uint32(1 hours),
        uint32(2 hours),
        uint32(4 hours),
        uint32(8 hours),
        uint32(16 hours),
        uint32(1 days),
        uint32(2 days),
        uint32(4 days),
        uint32(7 days)
    ];

    // An approximation of currently how many seconds are in between blocks.
    uint256 public secondsPerBlock = 15;

    /*** STORAGE ***/

    /// @dev An array containing the Kitty struct for all Kitties in existence. The ID
    ///  of each cat is actually an index into this array. Note that ID 0 is a negacat,
    ///  the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre
    ///  creature that is both matron and sire... to itself! Has an invalid genetic code.
    ///  In other words, cat ID 0 is invalid... ;-)
    Kitty[] kitties;

    /// @dev A mapping from cat IDs to the address that owns them. All cats have
    ///  some valid owner address, even gen0 cats are created with a non-zero owner.
    mapping (uint256 =&gt; address) public kittyIndexToOwner;

    // @dev A mapping from owner address to count of tokens that address owns.
    //  Used internally inside balanceOf() to resolve ownership count.
    mapping (address =&gt; uint256) ownershipTokenCount;

    /// @dev A mapping from KittyIDs to an address that has been approved to call
    ///  transferFrom(). Each Kitty can only have one approved address for transfer
    ///  at any time. A zero value means no approval is outstanding.
    mapping (uint256 =&gt; address) public kittyIndexToApproved;

    /// @dev A mapping from KittyIDs to an address that has been approved to use
    ///  this Kitty for siring via breedWith(). Each Kitty can only have one approved
    ///  address for siring at any time. A zero value means no approval is outstanding.
    mapping (uint256 =&gt; address) public sireAllowedToAddress;

    /// @dev The address of the ClockAuction contract that handles sales of Kitties. This
    ///  same contract handles both peer-to-peer sales as well as the gen0 sales which are
    ///  initiated every 15 minutes.
    SaleClockAuction public saleAuction;

    /// @dev The address of a custom ClockAuction subclassed contract that handles siring
    ///  auctions. Needs to be separate from saleAuction because the actions taken on success
    ///  after a sales and siring auction are quite different.
    SiringClockAuction public siringAuction;

    /// @dev Assigns ownership of a specific Kitty to an address.
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        // Since the number of kittens is capped to 2^32 we can't overflow this
        ownershipTokenCount[_to]++;
        // transfer ownership
        kittyIndexToOwner[_tokenId] = _to;
        // When creating new kittens _from is 0x0, but we can't account that address.
        if (_from != address(0)) {
            ownershipTokenCount[_from]--;
            // once the kitten is transferred also clear sire allowances
            delete sireAllowedToAddress[_tokenId];
            // clear any previously approved ownership exchange
            delete kittyIndexToApproved[_tokenId];
        }
        // Emit the transfer event.
        Transfer(_from, _to, _tokenId);
    }

    /// @dev An internal method that creates a new kitty and stores it. This
    ///  method doesn't do any checking and should only be called when the
    ///  input data is known to be valid. Will generate both a Birth event
    ///  and a Transfer event.
    /// @param _matronId The kitty ID of the matron of this cat (zero for gen0)
    /// @param _sireId The kitty ID of the sire of this cat (zero for gen0)
    /// @param _generation The generation number of this cat, must be computed by caller.
    /// @param _genes The kitty's genetic code.
    /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0)
    function _createKitty(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    )
        internal
        returns (uint)
    {
        // These requires are not strictly necessary, our calling code should make
        // sure that these conditions are never broken. However! _createKitty() is already
        // an expensive call (for storage), and it doesn't hurt to be especially careful
        // to ensure our data structures are always valid.
        require(_matronId == uint256(uint32(_matronId)));
        require(_sireId == uint256(uint32(_sireId)));
        require(_generation == uint256(uint16(_generation)));

        // New kitty starts with the same cooldown as parent gen/2
        uint16 cooldownIndex = uint16(_generation / 2);
        if (cooldownIndex &gt; 13) {
            cooldownIndex = 13;
        }

        Kitty memory _kitty = Kitty({
            genes: _genes,
            birthTime: uint64(now),
            cooldownEndBlock: 0,
            matronId: uint32(_matronId),
            sireId: uint32(_sireId),
            siringWithId: 0,
            cooldownIndex: cooldownIndex,
            generation: uint16(_generation)
        });
        uint256 newKittenId = kitties.push(_kitty) - 1;

        // It's probably never going to happen, 4 billion cats is A LOT, but
        // let's just be 100% sure we never let this happen.
        require(newKittenId == uint256(uint32(newKittenId)));

        // emit the birth event
        Birth(
            _owner,
            newKittenId,
            uint256(_kitty.matronId),
            uint256(_kitty.sireId),
            _kitty.genes
        );

        // This will assign ownership, and also emit the Transfer event as
        // per ERC721 draft
        _transfer(0, _owner, newKittenId);

        return newKittenId;
    }

    // Any C-level can fix how many seconds per blocks are currently observed.
    function setSecondsPerBlock(uint256 secs) external onlyCLevel {
        require(secs &lt; cooldowns[0]);
        secondsPerBlock = secs;
    }
}
</code></pre>

<p>Code Critique - CryptoKitties</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Artistic Convergence, AI + Critical Code + Critical Data Studies</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/76/code-critique-artistic-convergence-ai-critical-code-critical-data-studies</link>
        <pubDate>Sun, 02 Feb 2020 01:13:42 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Imani.Cooper</dc:creator>
        <guid isPermaLink="false">76@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Title</strong>: Artistic Convergence, AI + Critical Code + Critical Data Studies<br />
<strong>Author</strong>: Imani Cooper <br />
<strong>Language</strong>: No specific code just an invitation to think with me on AI, Code, and Data  <img src="http://wg20.criticalcodestudies.com/resources/emoji/smile.png" title=":)" alt=":)" height="20" /></p>

<p>Hi all, I wanted to start a thread to invite you to consider the role of code in contemporary gallery/ museum spaces as it is being used to further AI innovations.</p>

<p><strong>Background info</strong>––</p>

<p>I am currently a PhD student and I study code and algorithms as they intersect with experimental writing, and creative technologies that center notions of ancestral knowledge, movement, and self-becoming within black diasporas. My dissertation project examines 5 artistic projects that convey a genealogy of creative and critical approaches to data (both analog and digital) through a politics of gender and race. The analysis ends on a case study of a current art project using data and algorithmic driven technology, specifically Recursive Neural Networks (RNN) to make an AI sculpture engendered through data on three generations of black women experiences. In short, I encounter code the most in galleries, museums, artists’ studios, and creative community based workshops.  The code critique I am posting is concerning an art exhibition I went to at the Barbican Center in London called "AI More than Human". While initially I contemplated my experience from a Critical Data Studies perspective, I am most certainly interested in how a Critical Code Studies perspective can advance this line of thought!</p>

<p><strong>Code Critique / Inquiry</strong>––</p>

<p>In the exhibition AI: More than Human (2019) interactive digital art captivated the audience. Imagine, a large dimly lit crescent shaped room. Inside, a mild discordant hum of computer processing units (CPUs), flashing touch screens with various visual materials, these are some of the elements that characterized the breadth of artwork on display. An array of works by corporations and artist were presented including Affectiva, the leader in Human Perception AI, Mario Klingemann’s "Circuit Training", and Sony CSL’s "Kreyon City". For these select works ( however not limited to) the exhibition was a site to further train the neural networks of  AI and large databases with participants as data. I went to this exhibition to examine the speech patterns of  “Not The Only One” by Stephanie Dinkins (after its latest training session) but was struck by the exhibition as a whole. I read the moments of audience participation and their data contributions (some known and unknown) as a transformation of the Barbican gallery space into a kind of information research lab, and I am curious about this approach to data collection for AI, and use of code.</p>

<p>This line of inquiry is part of a larger ongoing thought process, but I would love to incite a generative discussion  considering: the role of code and data in the 21st century gallery/ museum space (especially the collaboration/juxtaposition of corporate and independent artist use)? How is code being enacted in this nuanced mode of artistic driven data collection? Would programming in Indigenous languages change the ethical terms of this data collection (especially for underserved communities) ?</p>

<p>Feel free to add and/or further along the questions!</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Boundaries of Ethical Code and Coding</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/79/code-critique-boundaries-of-ethical-code-and-coding</link>
        <pubDate>Sun, 02 Feb 2020 23:17:49 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>brycejackson</dc:creator>
        <guid isPermaLink="false">79@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>In thinking about ethics and code, we might first consider the different focuses of moral philosophy as meta, normative, or applied, traversing through truth value determination, Jeremy Bentham and John Stuart Mill’s arguments on utilitarianism or Immanuel Kant’s deontological declarations, or application of information, digital, technology, or code ethics.</p>

<p>One consideration of ethical coding is authorial intentionality of the code. Was the code written to add or remove functionality? Did the change correct logical or assumption flaws that caused unintentional outcomes – bug fixes? Was it modified to safeguard against potential security threats? Was something changed to purposely usurp control, creating a backdoor, of unwitting consumers of such code?</p>

<p>As Kevin Brock highlights in <em>Rhetorical Code Studies</em>, the code fix for Heartbleed, a security vulnerability in the <a rel="nofollow" href="https://www.openssl.org/" title="OpenSSL software">OpenSSL software</a>, was simple yet overlooked through multiple code contributions to the open source project. The fix added a few lines of code to perform two checks about the amount of data stored and expected to prevent bad actors from reading potential data not intended for them. Brock adds how activities around the security flaw “can and do…exert tremendous influence over how individuals and communities respond to and deal with the consequences of writing code” (10).</p>

<p>Borrowing from Stuart Power’s simple one-line PHP backdoor example from <a rel="nofollow" href="https://gist.github.com/sente/4dbb2b7bdda2647ba80b" title="GitHub">GitHub</a>, re-shown here:</p>

<pre><code>    &lt;!-- Simple PHP Backdoor By DK (One-Liner Version) --&gt;
    &lt;!-- Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd --&gt;
    &lt;?php if(isset($_REQUEST['cmd'])){ echo &quot;&lt;pre&gt;&quot;; $cmd = ($_REQUEST['cmd']); system($cmd); echo &quot;&lt;/pre&gt;&quot;; die; }?&gt;
</code></pre>

<p>We might be quick to assess the applied ethical intention of the code to be immoral or evil to some degree. While using it requires certain security measures of a server to be permissive, and it assumes a UNIX operating system based on usage example, the code provides a rudimentary method to run system commands by visiting the URL where this code might run.</p>

<p>Other lengthier examples of overt instances of what might be considered unethical code exists; however, examining the less obvious coding approaches, such as code and code bases in common use, as Brock highlights with OpenSSL, might lead to better design and development practices for projects with “good” intentions.</p>

<p>Some questions that come to mind in code examination as well as in the practice of code design and development are:</p>

<ul>
<li>At what stages of design and development do we confront ethical decisions and to what scale?</li>
<li>In <em>Ethical Programs: Hospitality and the Rhetorics of Software</em>, James Brown states, regarding ethical predicaments and decision-making in code, “these steps are not necessarily arrived at rationally, and they are not always the result of deliberation” (5). How might we examine code or code base, reflectively, to identify pivotal moments of ethical predicaments?</li>
<li>What might be some guiding principles towards more ethical coding practices?</li>
<li>Thinking of the one-line code example, at what threshold does code transform into algorithm or agent/actor with ethical intentionality? Does it take only one line of code?</li>
<li>Regarding environmental ethics, can code be ethical or unethical based on its level of resource and power consumption? Can we write code to be more environmentally friendly?</li>
</ul>

<h2>Works Cited</h2>

<p>Brock, Kevin. <em>Rhetorical Code Studies: Discovering Arguments in and around Code</em>. University of Michigan Press, 2019.<br />
Brown, James J. <em>Ethical Programs: Hospitality and the Rhetorics of Software</em>. University of Michigan Press, 2015.</p>
]]>
        </description>
    </item>
    <item>
        <title>Week 2: Indigenous Programming (Main thread)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/70/week-2-indigenous-programming-main-thread</link>
        <pubDate>Mon, 27 Jan 2020 17:50:07 +0000</pubDate>
        <category>2020 Week 2: Indigenous Programming</category>
        <dc:creator>Temkin</dc:creator>
        <guid isPermaLink="false">70@/index.php?p=/discussions</guid>
        <description><![CDATA[<h1>Indigenous Programming</h1>

<h2>by Jon Corbett, Outi Laiti, Jason Edward Lewis, Daniel Temkin</h2>

<p>Our group will discuss Indigenous Programming; that is, code and programming languages built on spoken and written Indigenous languages.</p>

<p>With the wider support for Unicode, there has been an uptick in languages that challenge English's dominance. The most widely remarked-upon in the academic community is <a rel="nofollow" href="https://esoteric.codes/blog/interview-with-ramsey-nasser">قلب by Ramsey Nasser</a>, an Arabic LISP (also discussed in the 2014 working group). It showed not just that such a language is possible, but through the difficulties in making it functional, illustrated the Western biases of tools used by programmers. Another example is <a rel="nofollow" href="https://github.com/anoniscoding/yorlang/">Yorlang</a>, a Yoruba-based programming language by Karounwi Anu, a Nigerian developer. He uses English with his clients, but Yoruba with his friends, and wanted to be able to write code in the language they consider their own.</p>

<p>Outi Laiti's <a rel="nofollow" href="https://lauda.ulapland.fi/handle/10024/62624">thesis on Ethnoprogramming</a> gives insight into these works. She shows how programming's hardware and software levels rest on a terminology level, which itself rests on a cultural level. People who are excluded from the cultural level may find the other levels more challenging and be discouraged from programming. Alternately, they may be forced to embrace an English-based programming language, thus reinforcing a colonial language’s dominance locally. As Laiti says, "If we want to see a new generation of computer programmers who blur the borders of language, gender and culture, the ethnic side of computing needs to be researched and discussed."</p>

<p>However, what sets apart indigenous languages specifically can be difficult to define. Even the term Indigenous itself is debated. In her thesis, Laiti remarks on how the term has been criticized in defining people by their connection to colonial history. However, she provides an outline that might be helpful: "Indigenous people have their own language. They have a small population inside a dominant culture of the country. They still practice their cultural traditions and at last, some of them live in a territory that is, or used to be, theirs. They identify themselves as Indigenous people." Part of the issue arises from Western concepts of Indigeneity as analogous, that regardless of geographic locale being Indigenous merely means non-European/Western. But to say, for example, that Indigenous people in Papua New Guinea share the same or similar political and cultural concerns of the Inuit people would be false. However, there is a commonality that could be seen as a Pan-Indigenous lens and that is the socio-political and cultural perspectives of Indigenous people collectively contest the power of assimilationist nation-states and strongly self-advocate for community sovereignty and autonomy.</p>

<p>Beyond the question of bringing these languages into the text of code are how Indigenous culture might shape programming language design at a deeper level. <a rel="nofollow" href="index.php?p=/discussion/71/week-2-cree">Jon Corbett’s Cree# language</a>, which we will look at more deeply in a code critique thread, serves as an example. In Cree#, each program begins with smudging, a command that mirrors the ceremonial cleansing practice common to many North American Native people. This practice in life is intended to clear the mind, ears, eyes, mouth, heart, body and spirit. In his digital incorporation of this ceremony, the smudge command clears the buffer, resets the virtual machine to an initial state, and prepares it for a new activity. This connects the computer’s activities to living practices and by extension becomes braided and harmonious with everyday life.</p>

<p>We invite you to join us in exploring these and other issues in Indigenous computation, with these questions in mind:</p>

<ul>
<li><p>With the advancements in language technologies (unicode, etc), why is 90% of all computing done in English still? Is this changing? Why can’t we write code in our ancestral languages?</p></li>
<li><p>What is uniquely at stake for Indigenous communities vs. other communities that happen to speak languages other than English?</p></li>
<li><p>How do we get code to reflect Indigenous thinking beyond just using relevant keywords? How can we bring the cultural logic of the community into the language?</p></li>
</ul>
]]>
        </description>
    </item>
    <item>
        <title>Call for Codebases</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/81/call-for-codebases</link>
        <pubDate>Mon, 03 Feb 2020 03:58:47 +0000</pubDate>
        <category>2020 General</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">81@/index.php?p=/discussions</guid>
        <description><![CDATA[<h1>Call for Codebases</h1>

<p>Before we begin code critiques, we have to find the bodies of code worth investigating.  Over the past ten years, we’ve looked at a wide range of code.  For example,</p>

<ul>
<li>The Apollo moon lander</li>
<li>ADVENTURE</li>
<li>FLOW-MATIC, a forerunner to COBOL</li>
<li>The Transborder Immigrant Tool</li>
</ul>

<p>It turns out one of the most productive intellectual contributions you can make to critical code studies is to identify a body of code worth considering.  That activity, of identifying an object worth analyzing, launches the investigation and incites exploration.</p>

<p>Why is this activity so important?  Primarily because to call out a body of code as worthy of exploration is to say this artifact has significance.  While CCS contends that all code has significance beyond what it does, for a scholar to turn a spotlight on a piece of code is like choosing a book for a book club or perhaps more significantly to present a work on on display in a museum.  In the same way the Code Critiques do, that act of curation gives the rest of us a chance to walk around and consider various aspects -- and we can help find snippets worth exploring further.</p>

<p>Let us begin this thread with a call for codebases -- a call for you to identify programs or entire pieces of software worth exploring.  These could be in repositories or merely a single file -- as long as the code is publically available for collective exploration.</p>

<p>So we put out the call to you? What codebases do you want to identify?</p>
]]>
        </description>
    </item>
    <item>
        <title>Week 1: Introduction to Critical Code Studies (Main thread)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/57/week-1-introduction-to-critical-code-studies-main-thread</link>
        <pubDate>Mon, 20 Jan 2020 17:08:59 +0000</pubDate>
        <category>2020 Week 1: Introduction to Critical Code Studies</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">57@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Jeremy Douglass and Mark C. Marino</strong></p>

<p><span data-youtube="youtube-631TRAcKqjs?autoplay=1"><a rel="nofollow" href="https://www.youtube.com/watch?v=631TRAcKqjs"><img src="https://img.youtube.com/vi/631TRAcKqjs/0.jpg" width="640" height="385" border="0" alt="image" /></a></span></p>

<p><br /></p>

<p>Welcome to the first week of the 2020 Critical Code Studies Working Group. During this week, we’ll be introducing critical code studies in general by means of the introductory chapter to the forthcoming book Critical Code Studies (The MIT Press). We’ll also take this week as an opportunity to introduce newcomers to the field but also to take stock in where the field has come and to look forward to where it is headed next.</p>

<blockquote><div>
  <p>Critical code studies names the applications of hermeneutics to the interpretation of the extrafunctional significance of computer computer source code…. Extra here means not outside of or in addition to but instead growing out of…. CCS holds that the lines of code of a program are not value-neutral and can be analyzed using the theoretical approaches applied to other semiotic systems, in addition to particular interpretive methods developed specifically for the discussions of programs.</p>
</div></blockquote>

<p>But what does it mean to explore culture through code?</p>

<p>Mark answers this question in the book, reading code as varied as the leaked software from the Climategate scandal to code written by media philosopher Friedrich Kittler. He reads art objects like the Transborder Immigrant Tool, variants of electronic literature works like Taroko Gorge, and code languages like the English-like precursor to COBOL, FLOW-MATIC.  He explores low level to high level languages, from ASSEMBLY to Inform 7, including languages in Arabic (قلب or ’alb), Hawiian (in the ʻAnuʻu project), and Cree. (For much more on Indigenous Programming, look forward to our Week 2 discussion).  In a medium most consider to be merely an operationalized mathematics, readings of code lead him to discuss issues of racial and ethnic bias and the gendered bias he calls encoded chauvinism.  These readings have grown out of and reference discussions from past Critical Code Studies Working Groups because these collectives, these gathering of such varied minds, have the ability to identify so many complex meanings.</p>

<p>In the epilogue to the CCS book, Mark claims we have reached a moment where “philosophers process, poets publish, and curators collect code knowing scholars will interpret it as discourse” (227) -- in other words, where the basic tenets of critical code studies, that code is meaningful, have been widely accepted. How does that acceptance change the culture of code? How does that facilitate what we are trying to do here?</p>

<p>Because code has become accepted as a means of expression, we now have new works choosing code as one of their communication channels.  Consider: Eugenio Tisselli's “Amazon” webpage, released over Twitter.  Created in response to this summer’s devastating fires, Tisselli’s code articulated his despair over the environmental effects of globalized capitalism. Code was able to serve as his language of expression because, as, Alex McCLean and Geoff Cox have written, Code Speaks.</p>

<blockquote><div>
  <p>see related discussion: <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/discussion/61/week-1-amazon-html-by-euguenio-tisselli">amazon.html by Euguenio Tisselli</a></p>
</div></blockquote>

<p>Code is a social medium and its meaning is also social.  The “critical” aspect of critical code studies looks to explore, among other aspects, this social dimension, especially as it pertains to power relations, across differences of race, gender, sexuality, and socio-economic status or class.  “Critical” code studies is not technological history at the service of digital industries, it is an exploration of human culture in code complete with biases, abuses, inconsistencies, and injustices.  CCS is an alternative to “uncritically documenting military-industrial-academic artifacts on behalf of those who created them to the benefit of their creators’ self-regard” (238). We aspire to more.</p>

<p>At the same time, it is worthwhile to look to critical theories and philosophical paradigms that you have found useful or would like to apply but perhaps can’t see how. Or maybe you have come across some code that you can’t read or can’t find a critical hand hold on. (This is a good time to introduce some of your code critique threads).</p>

<p>Programming has continued to evolve.  New and strange languages have emerged. With the advent of contemporary machine learning algorithms, more code is being generated by software, code that programmers may never deal with directly. How does meaning change in such contexts? As more people discuss algorithms, what can the study of code add to those conversations?</p>

<p>So we invite the CCS community to begin this week of the Working Group with a broad, reflexive conversation, a thread that invites you to look back and forward, that invites you to express your thoughts about the potential obstacles for critical code studies as well as your own insights and inspirations.</p>

<p><br /></p>

<hr />

<p>Some questions:</p>

<ul>
<li>What do you want to know about CCS?</li>
<li>What are the next challenges for Critical Code Studies? Current puzzles?</li>
<li>What projects would we like to launch in the coming years? An edited collection? Conference?</li>
<li>How has CCS been most productive?</li>
<li>What are some current questions or problems that CCS is uniquely suited to addressing?</li>
<li>What are the lacuna or blindspots--what should should CCS be addressing that it is not currently?</li>
</ul>

<p><br /></p>
]]>
        </description>
    </item>
    <item>
        <title>Programming 3D virtual reality environments at k12 levels through using Web3D based languages</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/98/programming-3d-virtual-reality-environments-at-k12-levels-through-using-web3d-based-languages</link>
        <pubDate>Sun, 09 Feb 2020 20:52:44 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>jorge.franco</dc:creator>
        <guid isPermaLink="false">98@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Jorge Franco</p>

<p>Language - Extensible 3D (X3D) - (Technical support <a href="https://www.web3d.org/" rel="nofollow">https://www.web3d.org/</a>)</p>

<p>X3D - Features - <a href="https://www.web3d.org/sites/default/files/page/X3D%20Version%204%20Overview/FutureOfX3D.pdf" rel="nofollow">https://www.web3d.org/sites/default/files/page/X3D Version 4 Overview/FutureOfX3D.pdf</a></p>

<p>X3D version 4 - Draft - <a href="https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-WD1/" rel="nofollow">https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-WD1/</a></p>

<p>Software and hardware requirements - For programming on-line we can use the HTML Editor of a blog related to the Google (Blogger.com) platform and the (X3Dom framework features (<a href="https://www.x3dom.org/" rel="nofollow">https://www.x3dom.org/</a>). Any browser and computer devices able to run webgl graphical libraries related to the X3Dom framework.</p>

<p>Alternatively, for the places without online resources and connectivity, use standalone open source browsers such as (Freewrl working on personal computers and mobile android systems (<a href="http://freewrl.sourceforge.net/" rel="nofollow">http://freewrl.sourceforge.net/</a>)) and or the instant reality framework  (<a href="https://www.instantreality.org/" rel="nofollow">https://www.instantreality.org/</a>) for personal computers. There is also Titania X3D editor for Linux users (<a href="http://create3000.de/titania/whats-new/" rel="nofollow">http://create3000.de/titania/whats-new/</a> -  <a href="http://create3000.de/users-guide/" rel="nofollow">http://create3000.de/users-guide/</a>)</p>

<p>The K-12 educational context of using X3D language for inspiring students and educators' coding literacy is that such language and tools have gained sustainable accessibility. This accessibility has addressed problems of how to use advanced digital computing resources for deepening technical and scientific knowledge in an integrated way. An example of this possibility is analyzed  through the following code created in 2019 for supporting an before/after-school project and experimental computing education processes 8th grade individuals' learning and applying scientific concepts. (For testing it, the code bellow can be visualized in a blog HTML editor or at codepen org text editor (<a href="https://codepen.io/education/" rel="nofollow">https://codepen.io/education/</a>).</p>

<p>Code:</p>

<p> <br />
         <br />
            Our First 3D Virtual Reality Museum<br />
              <br />
             <br />
         <br />
         <br />
            </p><h1>3D Virtual Reality in November at Ernani Primary School!</h1> <br />
            <p> <br />
                Our first complex 3D digital content production work. <br />
            </p> <br />
                  <p> <br />
                 Nosso primeiro trabalho de conteúdo digital complexo. <br />
                  </p>



<pre><code>      &lt;x3d width='1400px' height='900px'&gt; 
        &lt;scene&gt; 
</code></pre>

<p><br />
</p>

<p></p>

<p><br />
 </p>



<pre><code>          &lt;transform translation='0 0 0'&gt; 
              &lt;shape&gt; 
                    &lt;appearance&gt; 
                             &lt;material diffuseColor='1 0 0'&gt;&lt;/material&gt; 
                  &lt;/appearance&gt; 
                          &lt;box size= '60.0, 0.1, 90.0' solid='false'&gt;&lt;/box&gt; 
               &lt;/shape&gt; 
           &lt;/transform&gt; 
</code></pre>



<pre><code>          &lt;transform translation='-25 5 0'&gt; 
              &lt;shape&gt; 
                    &lt;appearance&gt; 
                             &lt;material diffuseColor='0 0 1'   transparency='0.5'    &gt;&lt;/material&gt; 
                  &lt;/appearance&gt; 
                          &lt;box size= '0.5, 10.0, 90.0' solid='false'&gt;&lt;/box&gt; 
               &lt;/shape&gt; 
           &lt;/transform&gt;    
</code></pre>



<pre><code>          &lt;transform translation='-24.8 5 -30'&gt; 
              &lt;shape&gt; 
                    &lt;appearance&gt; 
                      &lt;ImageTexture  url=&quot;https://scontent.fcgh11-1.fna.fbcdn.net/v/t1.0-9/73495085_10157162660278393_5012001546217455616_n.jpg?_nc_cat=109&amp;_nc_oc=AQnzj8J-BiwWBDQp9hyX7Z855Y2aLB4jXl4ZylXsQhWV0n3BfuMtCAYQp_qdXO3l6ns&amp;_nc_ht=scontent.fcgh11-1.fna&amp;oh=387c183fc4e0b252e1e8151a066ff9c4&amp;oe=5E5966E8&quot;&gt;&lt;ImageTexture/&gt;
                             &lt;material diffuseColor='0 1 0'   transparency='0.2'    &gt;&lt;/material&gt; 
                  &lt;/appearance&gt; 
                          &lt;box size= '0.2, 7.0, 14.0' solid='false'&gt;&lt;/box&gt; 
               &lt;/shape&gt; 
           &lt;/transform&gt;    
</code></pre>

<p><br />
<br />
               <br />
                   <br />
                         <br />
                          <br />
                                  <br />
                       <br />
                               <br />
                    <br />
               </p>



<pre><code>          &lt;transform translation='-24.8 5 30'&gt; 
              &lt;shape&gt; 
                    &lt;appearance&gt; 
                     &lt;ImageTexture  url=&quot;https://scontent.fcgh11-1.fna.fbcdn.net/v/t1.0-9/74290224_10157188420193393_5945857161560064000_n.jpg?_nc_cat=106&amp;_nc_oc=AQl_jFIYgphh3gK4soJOln3Jvz-k3Uddk7ZlgETCB-1MKOMbifW7Ba3yJGhvCprQJSY&amp;_nc_ht=scontent.fcgh11-1.fna&amp;oh=dd8fb33e87a60dc03940ce35254da2e2&amp;oe=5E4CF0E6&quot;&gt;&lt;ImageTexture/&gt;
                             &lt;material diffuseColor='0 1 0'   transparency='0.2'    &gt;&lt;/material&gt; 
                  &lt;/appearance&gt; 
                          &lt;box size= '0.2, 9.0, 12.0' solid='false'&gt;&lt;/box&gt; 
               &lt;/shape&gt; 
           &lt;/transform&gt;    

        &lt;/scene&gt; 
     &lt;/x3d&gt; 
</code></pre>

<p>Visualization Image in Codepen editor:</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/rk/pnq172ulqxt5.jpg" alt="" title="" /></p>

<p>The accessibility and modularity of the X3D language through the X3Dom framework has allowed to use it for supporting before/after-school computing education projects. However, attempting to integrate the projects dynamics with learning and teaching scientific concepts from the k-12 curriculum as explained in the quote bellow.<br />
"This code literacy case highlights a connection between real and virtual worlds, extending the source code analyses of figure 1 (b), in section 2.1, with HCI at ESB’s school lab and beyond. For example, there is a meaning of using a (real) ruler and comparing its functionalities with the ones of the (virtual and non-visible / immaterial software behind the scene of the digital box described) in the command line ( ) in the figure 1 (b) (<strong>text in blue picture below</strong>). This objects comparison helped author 1 and a student from 8th grade communicative processes. By comparing the Cartesian coordinate system X, Y and Z with the ruler measuring functionalities they got insights related to decimal numbers (0.4) and size proportions, encompassing ((length (X), height (Y) and depth (z)) through real time sensorial and multidimensional stimuli based on applying VR and its features like physical and mental immersion, sensory feedback and interactivity. The described objects’ connection inspired visual and tactile interactions via reading a programming code template on a sheet of paper and digitizing (reading through writing) code source via a keyboard, in the figure 2 (b), and visualizing the symbolic representation of the code programmed in the form of a 3D rectangular geometric object placed in the 3D interactive interface produced utilizing principles of digital storytelling in a blog created by the student [49]. It includes, navigating the blog 3D scenery with a mouse for interacting with this particular piece of 3DVR rectangle object created using the blog HTML text editor for coding X3D language algorithms linked with computer graphics libraries related to the X3Dom framework. These design, creative, participatory, communicative and 3D navigation starting point processes stimulated the production of new 3D objects. Such production processes implicated in stimulating ones’ spatial reasoning materialized through transforming and translating the initial 3D rectangle shape and position throughout reusing the initial source code. For that, the student reused two command lines successively (first  for reshaping the rectangle and second  for moving it to diverse positions) until the adapted rectangle pieces together form a box with four lateral walls as showed in the figure 2 (d) on the computer screen (<strong>educator programming using Code pen editor - picture bellow</strong>)." (Franco; Oliveira, 2019)</p>

<p><strong>text in blue picture below</strong><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/pq/n6hcilb3tpze.jpg" alt="" title="" /></p>

<p><strong>educator programming using Code pen editor - picture bellow</strong><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/zc/1qak9sla4546.jpg" alt="" title="" /></p>

<p>This type of computing education at k-12 levels has addressed how to inspire inclusive and equality education in terms of gender and ethnicity knowledge enhancements and participation in computing. It includes inspiring ones' tacit knowledge application in lifelong learning attitudes (FRANCO et al., 2007(<a href="https://www.researchgate.net/publication/260386601_DEVELOPING_INTERACTIVE_EDUCATIONAL_ENVIRONMENTS_TO_STIMULATE_LIFELONG_LEARNING" rel="nofollow">https://www.researchgate.net/publication/260386601_DEVELOPING_INTERACTIVE_EDUCATIONAL_ENVIRONMENTS_TO_STIMULATE_LIFELONG_LEARNING</a>)  ;FRANCO; LOPES, 2012 -<a href="https://www.intechopen.com/books/computer-graphics/developing-an-interactive-knowledge-based-learning-framework-" rel="nofollow">https://www.intechopen.com/books/computer-graphics/developing-an-interactive-knowledge-based-learning-framework-</a> ) beyond a reductionist technical perspective of reading and writing computer code (BROCK, 2019, <a href="https://www.researchgate.net/project/Rhetorical-Code-Studies" rel="nofollow">https://www.researchgate.net/project/Rhetorical-Code-Studies</a>).</p>

<p>Individuals improving reading and writing skills through acquiring and developing coding and visual literacy abilities.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/vi/2vz0hpg044nf.jpg" alt="" title="" /></p>

<p>Enhancing Educators' digital skills in service preparation</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/g9/59rqeq9aukze.jpg" alt="" title="" /></p>

<p>Gender and ethnicity inclusion and equality in computing education using a connection between real and virtual resources through acquiring and applying digital and scientific knowledge at the natural environment of school computers lab since k-12 levels.</p>

<p>Example 1 - 8th grade students and educator during computational practices at school computer lab<br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/99/hmtrje7o434u.jpg" alt="" title="" /></p>

<p>Example 2 - reading, writing, communicating through acquiring coding literacy using a connection between real and virtual materials<br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/ol/kecj7bckinqw.jpg" alt="" title="" /></p>

<p>Blogs construction are some results of a 8 week interactive and collaborative knowledge based computing education processes with 8th grade students at the end of 2019.</p>

<p><a href="https://vitorick.blogspot.com/2019/11/3d.html" rel="nofollow">https://vitorick.blogspot.com/2019/11/3d.html</a><br />
<a href="https://lauraevellynmariafernanda.blogspot.com/" rel="nofollow">https://lauraevellynmariafernanda.blogspot.com/</a></p>

<p>Educators blogs<br />
<a href="https://experiencyas.blogspot.com/2019/09/blog-post_28.html" rel="nofollow">https://experiencyas.blogspot.com/2019/09/blog-post_28.html</a><br />
<a href="http://englishartworkaternaniprimaryschool.blogspot.com/" rel="nofollow">http://englishartworkaternaniprimaryschool.blogspot.com/</a></p>
]]>
        </description>
    </item>
    <item>
        <title>Tick in Unreal Engine</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/63/tick-in-unreal-engine</link>
        <pubDate>Tue, 21 Jan 2020 19:49:56 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>alvarotriana</dc:creator>
        <guid isPermaLink="false">63@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Title:</strong> Tick<br />
<strong>By:</strong> Epic Games<br />
<strong>Code:</strong> C++</p>

<p><code>*Function called every frame on this Actor. Override this function to implement custom logic to be executed every frame.  *Note that Tick is disabled by default, and you will need to check PrimaryActorTick.bCanEverTick is set to true to enable it.  * *@param DeltaSeconds    Game time elapsed during last frame modified by the time dilation</code></p>

<p><code>virtual void Tick( float DeltaSeconds );</code></p>

<p><strong>Overview</strong><br />
Tick is the method used on Unreal Engine to allow programmers to execute code before each frame of the game is rendered.<br />
This code is executed several times per second, and it's critical for the overall performance of the game. In a conservative scenario, a video game rendering at 30 frames per second will call this function at least one time for each actor.</p>

<p><strong>Questions for Discussion</strong> <br />
Some of my questions are derived from my lack of experience in academic research, so please bear with me <img src="http://wg20.criticalcodestudies.com/resources/emoji/smile.png" title=":smile:" alt=":smile:" height="20" /></p>

<ul>
<li>The sample code is the virtual declaration of the method. There are several implementations of it in the Unreal Engine source code and a lot more for each custom implementation. Should I work with the virtual declaration or use some of the definitions?</li>
<li>One of the subjects that interest me is the power hierarchy that Game Engines have. Maybe it would be interesting to dig into the power relationships that this kind of structure can create between the engine's creators and the developers using that technology. I would love to hear your opinions on this.</li>
<li>The other subject is related to the human perception and this kind of code that executes at great speed and makes a lot of operations to generate the images we see in a video game. The thing with this option is that I don't know where to start <img src="http://wg20.criticalcodestudies.com/resources/emoji/confused.png" title=":/" alt=":/" height="20" /></li>
<li>I also would love to hear any other ideas</li>
</ul>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Transgressive coding: IRL Embodiment &amp; Fluid Coding</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/82/code-critique-transgressive-coding-irl-embodiment-fluid-coding</link>
        <pubDate>Mon, 03 Feb 2020 04:29:57 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>patricia_s</dc:creator>
        <guid isPermaLink="false">82@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>How can code transgress our understanding of human experiences that don’t conform to the heteronormative, binarist social order? What can fluid forms of coding contribute to our understanding of orientation fluidity, and gender fluidity? I am bringing this up as a member of both of these diverse communities, because I think about this all the time. I’m interested in learning about what fluid forms of coding (HTML/CSS/Javascript)** can offer digital infrastructures aimed at respatializing real life embodiment.</p>

<p>There is a rich history of queer subcultures sending coded messaging to each other. A message that only an insider would parse. Historically, in the Western world people assigned female at birth have used various codes to signal their queerness: neckwear, hairstyle, keychains, rings, and more. People assigned male at birth (and particularly within working classes) developed a sophisticated “hanky code” for communicating varying levels of interest in specific forms of engagement. Someone outside queer subculture wouldn’t think much of seeing a light blue bandana on someone’s back pocket, on the right side. To a person who can read that message, that communicates that the wearer is interested in providing oral sex. Historically, this has been an act of hiding in plain sight, and a way for people to find each other and connect efficiently, with or without words. It’s a very customized usage of presentation to communicate preferences outside dominant social norms.</p>

<p>Since front end coding performs acts of presentation, I’m interested in what can adaptive, fluid coding contribute to how bodies in real life transgress dominant social norms. In my view, possibilities can become examples, and examples can become referent points for progress.</p>

<p>Looking for an answer to this question led me to one project addressing gender fluidity, but this project was specifically about mapping human experience, and visualizing data points/feelings: <a rel="nofollow" href="https://www.gaytascience.com/plot-me-genderfluid/" title="Plot me Genderfluid">Plot me Genderfluid</a>.  There’s so much value in this project, from so many points of inquiry, I enjoyed it so much! Yet, Plot me Genderfluid remains within the limitations of ‘code as we know it’ not code being questioned, or summoned to challenge our own imagination in real life. Not because coding is by itself some kind of oracle, but because it can bring about new points of/for inquiry. Plot me Genderfluid exposes, it does not instigate.</p>

<p>Increasingly we talk about how less dominant forms of gaming and mobile games can be a catalyst for empathy. An example of this is the mobile game Bury Me, My Love in which the Syrian refugee crisis is the setting for experiences designed for the player to feel empathy. But we don't consider code that way, do we? We don't discuss code as having the potential of generating empathy through its syntax, composition, and delivery (of an experience, rather than data).</p>

<p>My questions to the group are:</p>

<p>1) How can we shape fluid modes of coding so that such forms can instigate forms of transgression? Specifically, through experiences, not just the presentation of data.</p>

<p>2) How can fluid syntaxes invite us to imagine ways of being more at ease in the real world, as queer people? As a member of marginalized communities?</p>

<p>3) What we can do to respatialize micro*** digital infrastructures to prioritize equity in real life?</p>

<p>How each of these possibilities are made, navigated, and re-ordered is of high interest to me.</p>

<p>Notes:<br />
** I’m specifically discussing the only fluid forms of coding I have experience with (HTML, CSS, Javascript), but I’m open to knowing about other forms of fluid coding that are front-end based and structured to be adaptive.</p>

<p>*** I use 'micro' to mean individually crafted, independent projects, rather than a 'macro' apparatus, an existing corporate entity, or projects derived from existing corporate legacy products. Example: micro=github; macro=Oracle</p>

<p>For further reading:<br />
<a rel="nofollow" href="https://www.out.com/out-exclusives/2017/6/19/untucking-queer-history-colorful-hanky-code" title="Untucking the Queer History of the Colorful Hanky Code">Untucking the Queer History of the Colorful Hanky Code</a>, Out.com, June 2019.</p>
]]>
        </description>
    </item>
    <item>
        <title>FloodNet: Deliberate Error as Protest and Performance</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/96/floodnet-deliberate-error-as-protest-and-performance</link>
        <pubDate>Sun, 09 Feb 2020 07:08:48 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Ignotus_Mago</dc:creator>
        <guid isPermaLink="false">96@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Before I begin, I want to note that this code critique is a collaborative effort of Shawné Michelain Hollaway and myself, Paul Hertz. We have a common interest in the performative and social aspects of algorithms and code: how social interactions are encoded in culture and how artists can create coded performances as a social (inter)action.</p>

<p>I am going to start things off by introducing our topic. Shawné will respond. Then I'll post some code examples. Following that, we hope to engage in an open-ended dialog, which we invite CCSWG participants to join.</p>

<p>FloodNet was developed in 1998 by the Electronic Disturbance Theater (EDT), a group of artists and activists working in the area of Electronic Civil Disobedience (ECD). FloodNet enabled activists to hold "virtual sit-ins." Using HTML pages and some minimalist Java code, participants could stage an online protest by flooding a targeted server with repeated requests for pages. Typically, a time would be set for the protest, participants would open the FloodNet home page during the protest and an applet embedded in the page would send out requests from the client page to the targeted server every 7 seconds. Participants could also send "personal messages" encoded as URLs to the server. The client would request a non-existent page, causing the server to generate and log a "404 Page Not Found" error, for example: "welcome//impartiality/_and_respect not found" or "welcome//human_rights/_and_dignity not found". If enough people participated, they would have a noticeable impact on the server response time, potentially flooding it with so many requests that it would crash. In other words, FloodNet operated as a DDoS (Distributed Denial of Service) attack.</p>

<p>DDoS as protest was controversial from the start. As Geert Lovink notes, "...hackers were divided over the effectiveness of the Floodnet software[...]. Libertarian minded hackers suggested that the 'flooding' of corporate and government servers was ending up nowhere. Massive hit attacks, directed at the enemy site were getting lost in the general net, thereby mostly harming others, in particular your local ISP." Governments also took notice and began taking steps to make such attacks illegal, conflating political DDoS with terrorist attacks on the Internet. [Lovink 2002, pp. 254-274]</p>

<p>The most well-known use of FloodNet was in a series of protests in support of the Zapatista social movement (or "insurgency" as sources in the Mexican government would have it) in the state of Chiapas, Mexico. Without going into the depth that the topic deserves, I would note that the Zapatista Movement, which continues to the present day, offered models of decentralized organization both in its political philosophy (i.e., having as its public face "Sub-Comandante" Marcos, who functioned more as a spokesperson than a leader meting out decisions) and in its cultural roots as an indigenous movement protesting among other injustices the <em>latifundio</em> system of land ownership brought by the Spanish colonists, which saw shared ownership and cultivation reduced to single ownership over vaste expanses and cultivation ordered "<em>a dedo</em>," by pointing to whomever would be given work in a pool of marginally employed day-laborers. The Zapatista Movement was very savvy in its use of media, and in many respects centered its strategies around defensive or non-violent protest actions, community organization, and occupation of lands. The style and open organization of the Zapatistas appealed to many political activists outside Mexico.</p>

<p>Our concern in examining the FloodNet codebase, however, is not with its historical setting so much as with two concepts within its form of social activism that are embedded in the code. First, as artists who have worked within the Chicago Dirty New Media and international Glitch Art movements (where <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%23Chicago&amp;Mode=like">#Chicago</a> is a non-locative hashtag), we are fascinated by intentional error as a tactic and specifically by the creative use of 404 errors. These errors present themselves in server logs, where they will eventually be read by a human operator, and are performed, captured, and spread on the client side as an ironic souvenir or token to be passed around. Secondly, we want to foreground the ways in which DDoS as Electronic Civil Disobedience is distinct from malicious DDoS, ways that are embedded in the codebase and the performed actions: activists do not hide their identities and may well sign their names; servers are not anonymized.</p>

<p>Regarding the FloodNet codebase: the source code for the Java applets is missing. The original developers from EDT could not find it. However, opening the .class files in a text editor reveals embedded strings scattered through the non-ASCII, and these strings tell a story. The HTML pages also provide clues, but for the sake of focus, we will dig into the .class files, viewed as texts.</p>

<p>Source for a "developer's kit" version of FloodNet can be downloaded from <a href="http://www.thing.net/~rdom/ecd/jan99ddk.zip" rel="nofollow">http://www.thing.net/~rdom/ecd/jan99ddk.zip</a>. FloodNet's Zapatista protest is running in emulation in the Rhizome net.art archive, at <a href="https://sites.rhizome.org/anthology/floodnet.html" rel="nofollow">https://sites.rhizome.org/anthology/floodnet.html</a>. I have also downloaded the Rhizome HTML and .class files, so we will occasionally cite them.</p>

<hr />

<p>Lovink, Geert, An Insider's Guide to Tactical Media. from Dark Fiber, MIT Press, 2002, pp. 254-274</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Plan 9 cat</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/84/code-critique-plan-9-cat</link>
        <pubDate>Mon, 03 Feb 2020 11:36:47 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>osnr</dc:creator>
        <guid isPermaLink="false">84@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Plan 9 <a rel="nofollow" href="https://9p.io/sources/plan9/sys/src/cmd/cat.c" title="cat">cat</a><br />
Author/s: not stated (Rob Pike?)<br />
Language/s: C<br />
Year/s of development: late 1980s<br />
Software/hardware requirements (if applicable): Plan 9 OS, or <a rel="nofollow" href="https://github.com/9fans/plan9port" title="plan9port">plan9port</a> on Mac/Linux</p>

<p>cat is a command-line utility that was included in the original 1970s Unix: it reads one or more files from disk and writes all their content out together (con_cat_enates) to the console. It still exists on all Mac and Linux computers today. As the manual page on my Mac laptop says,</p>

<blockquote><div>
  <p>The command:</p>

<pre><code>cat file1
</code></pre>
  
  <p>will print the contents of file1 to the standard output.</p>
  
  <p>The command:</p>

<pre><code>cat file1 file2 &gt; file3
</code></pre>
  
  <p>will sequentially print the contents of file1 and file2 to the file<br />
  file3, truncating file3 if it already exists.  See the manual page for<br />
  your shell (i.e., sh(1)) for more information on redirection.</p>
</div></blockquote>

<p>I want to discuss the version of cat in <em>Plan 9 from Bell Labs</em>, an operating system written to be a 'spiritual successor' to Unix in the 1980s and 1990s (by some of the same people who originally did Unix in the 1970s). The authors of Plan 9 felt that Unix had accumulated "cruft" in the hands of other engineers and researchers and that its "spirit" had been lost. They wanted to excise concepts and subsystems that they felt were outdated or unnecessary. They seemed driven to achieve what they saw as aesthetic unity and clarity.</p>

<p>One of Plan 9's authors said that Plan 9 was meant to be <a rel="nofollow" href="http://9front.org/press/sdtimes/sdtimes.article" title="&quot;an argument for simplicity and restraint&quot;">"an argument for simplicity and restraint"</a> -- an operating system as a kind of argument!</p>

<p>cat was a sort of flashpoint or key example for that argument. Before Plan 9, some of its eventual authors gave a presentation, <a rel="nofollow" href="http://harmful.cat-v.org/cat-v/" title="&quot;cat -v Considered Harmful&quot;">"cat -v Considered Harmful"</a>, which criticized the growth of cat under outside organizations like UC Berkeley's Unix research group -- they criticized the addition of features and options like <code>-v</code> to the <code>cat</code> program which had once had a single clear purpose.</p>

<p>So Plan 9's cat (in contrast to Unix's cat) is quite short:</p>

<pre><code>#include &lt;u.h&gt;
#include &lt;libc.h&gt;

void
cat(int f, char *s)
{
    char buf[8192];
    long n;

    while((n=read(f, buf, (long)sizeof buf))&gt;0)
        if(write(1, buf, n)!=n)
            sysfatal(&quot;write error copying %s: %r&quot;, s);
    if(n &lt; 0)
        sysfatal(&quot;error reading %s: %r&quot;, s);
}

void
main(int argc, char *argv[])
{
    int f, i;

    argv0 = &quot;cat&quot;;
    if(argc == 1)
        cat(0, &quot;&lt;stdin&gt;&quot;);
    else for(i=1; i&lt;argc; i++){
        f = open(argv[i], OREAD);
        if(f &lt; 0)
            sysfatal(&quot;can't open %s: %r&quot;, argv[i]);
        else{
            cat(f, argv[i]);
            close(f);
        }
    }
    exits(0);
}
</code></pre>

<p>Even before looking at the code itself, notice that it is so short: 35 lines.<br />
<a rel="nofollow" href="https://github.com/pete/cats/blob/master/gnu-cat.c" title="GNU's cat">GNU's cat</a> (the descendant of Unix cat used in Linux) is almost 800 lines, and <a rel="nofollow" href="https://www.reddit.com/r/UnixHumor/comments/aapgv3/long_cat_is_long_code_size_comparison_of_plan9s/" title="people joke about the difference between the two cats">people joke about the difference between the two cats</a>. The brevity of Plan 9's cat (while still providing the basic functionality of cat) is part of the argument: "you don't need all that stuff."</p>

<p>Why are the two programs so different in size? What is omitted in Plan 9 that GNU includes? (right at the top, authorship and copyright information, for instance!) Is everything in GNU really just "cruft"?</p>

<p>What kinds of user and programmer does this Plan 9 argument of simplicity privilege? For instance, the GNU cat claims to be faster (benefitting end users who are using the utility), while the Plan 9 cat may be easier to understand (benefitting programmers who want to learn how the system works). Is it better to have one large program (like GNU cat) that people can learn with many options and features based on what users seem to actually want, or many simple programs (as in Plan 9) that people need to compose together on their own?</p>

<p>Finally, what does the (terse, short variable names, uncommented) code style of Plan 9's cat tell you about the values of its creators? Every line here seems to be written with the assumption that its meaning will be obvious to the reader: for example, it seems to be assumed that the reader will know that <code>f</code> names a file descriptor and that 0 and 1 are standard input and output. Contrast with GNU's cat, which has longer variable names, has extensive comments, and uses <code>input_desc</code>, <code>stdin</code>, and <code>stdout</code>, not <code>f</code>, 0, and 1. But at the same time, overall, isn't GNU's cat still much longer and so more difficult for a reader to understand in full?</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique:  Feminist decolonial, Indigenous, and queer STS Approaches to AI and the Human</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/94/code-critique-feminist-decolonial-indigenous-and-queer-sts-approaches-to-ai-and-the-human</link>
        <pubDate>Fri, 07 Feb 2020 02:15:37 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>lfoster</dc:creator>
        <guid isPermaLink="false">94@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Much of my work is at the nexus of feminist decolonial, Indigenous, and queer STS; African studies; and socio-legal studies. We are currently working on a project that conducts a discourse analysis of how media sources directed at and by audiences across the continent of Africa are articulating and giving meaning to technologies of artificial intelligence and machine-learning. In reading across several sets of literature for this project, I have been considering two questions:</p>

<ol>
<li><p>How does the field of critical code studies draw upon and diverge from feminist decolonial, Indigenous, and queer STS? I wonder what intellectual geneaologies are informing the "critical" in critical code studies?</p></li>
<li><p>How might the study of source code enable new understandings of the human and the normative body, while also offering possbilities for building alternative ways of knowing and becoming?</p></li>
</ol>

<p>In our research, we have found that media sources, as producers of culture, promote an understanding of AI technologies through a language of modernity and progress. For example, media sources promise that AI will be fast, efficient, productive, adaptable, certain, and precise. How does this inform our conceptions of what it means to be valued as human and/or devalued as less than human?</p>

<p>What would an alternative vision of AI technologies look like? Is it possible to imagine a more inclusive AI future with source code that enables slower movement, sideways thinking (Puar), queer use (Ahmed), situated knowledges (Haraway), queer failure (Halberstam)?</p>

<ul>
<li>Laura</li>
</ul>
]]>
        </description>
    </item>
    <item>
        <title>Old Programs, Glitches, and Developing a Repository of Old Game Code</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/83/old-programs-glitches-and-developing-a-repository-of-old-game-code</link>
        <pubDate>Mon, 03 Feb 2020 05:19:48 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Jordan.Clapper</dc:creator>
        <guid isPermaLink="false">83@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>My first engagement with coding of any kind occurred when I was very young in the form of video games, and it was in the form of a glitch. My first game console was the Sega Genesis, and I first thought about coding through a common occurrence for those that play games, especially in those early years: the glitch.</p>

<p>Most of the time, when one plays games, we may not be explicitly thinking about the underlying code that assembles that game, even though it pervades every facet of that game. I never thought about games as being digital assemblages until I met my first unintended glitch. At the end of a stage in Sonic the Hedgehog 2, if one has collected all of the Chaos Emeralds and still has enough rings (over 50) after passing the end of the stage, if the player jumps, the character sprite, the titular Sonic, will light up and appear to change into his super form. However, he begins running in the air after the end stage screen begins to play. The points are tallied up, and then...nothing. He just keeps running, and the stage never progresses. I was "softlocked," the game not ending but progress completely halted because some condition is not being met, an unrecoverable situation. When this first happened, I was frustrated, thinking the game was broken. I reset the console, and I regained all of my progress after some work.</p>

<p>I learned to play video games before I learned to read. Since my younger years, my brain has often worked through these various systems that I encountered, from planning out my day, to how I can make an intolerable activity more interesting by treating it like a programmed task: assigning points, beating challenges, besting my previous times. It wasn't until a few years after the aforementioned Sonic glitch that I found myself experimenting with glitches intentionally in my playing.</p>

<p>In Pokemon Red/Blue for the Gameboy, there is a series of steps that one can take to make it so one's items in a particular slot in the inventory are multiplied to the game's max value: 256. I learned about this exploit in a gaming magazine, where they laid out all of the steps to do this process, something unintended by the game's developers, GameFreak. I felt like I had broken the rules, replicating items until I had enough to easily level all of my Pokemon to Level 100, the game's maximum level for individual monsters. But it saved me time, and when I linked in (through an analog cable) with my classmates at school, I easily won out. Until the glitch became commonplace.</p>

<p>In performing this glitch, one would encounter the infamous "Missingno.", a glitchy mess of sprite values that looked like a mutant Tetris piece (<a href="https://vignette.wikia.nocookie.net/pokemontowerdefense/images/c/ce/Missingno_image.png/revision/latest?cb=20180809204127" rel="nofollow">https://vignette.wikia.nocookie.net/pokemontowerdefense/images/c/ce/Missingno_image.png/revision/latest?cb=20180809204127</a>). The magazine I had read warned not to catch this glitch. It would create a mess of one's save file, and the data would be irretrievable. Now that everyone had maxed out Pokemon, I became curious. I thought back to messing up my game a few years back. I had other copies of Pokemon games from that generation. I traded some of my better Pokemon to other games, and I set about ruining my copy of Pokemon Blue. I caught the Pokemon, and it let out a cry that sounded like mangled copies of the other monsters, randomly bringing up sprites from those other Pokemon. Steadily, my game became unplayable, refusing to even open the last time I tried to activate my game file. I had glitched out my entire experience, and I had to reset the game.</p>

<p>There are a number of reasons for this glitching problem. Ones involves "memory mapping" in those early years of limited memory and storage space. The code used in Gameboy games, often programmed in C and then transferred to binary coding on the cartridges, needed to point to specific locations in order to read what it was supposed to do.</p>

<p>Link to a deconstruction of Pokemon Red: <a href="https://github.com/pret/pokered" rel="nofollow">https://github.com/pret/pokered</a></p>

<p>This glitch, (in)famous for those of us who played it back when, was almost like a rite of passage. Once you'd done what you wanted in the game, this was a way to push the game beyond its intended limits. After that, I found myself seeking out glitches. Could I break through this wall and walk outside of a level? Could I discover something the developers didn't want me to see? Could I crash the game purposefully? In my earlier years, this was somewhat easier, as the exploits were understood through the limited scope of the programming back then. Not to say that exploits aren't possible now (speedrunning communities are dedicated to discovering every unintended coding effect to make the completion of a game faster), but back then there was something ethereal about playing a game both within and without boundaries to the experience.</p>

<p>That's something I'm interested in exploring as I seek to develop games from an indigenous/queer perspective: embracing the glitch. There's something to be explored within "poor programming," or rather, programming within constraints that necessitate a certain cleverness. In the above example, Pokemon Red is a game that is both iconic and incredibly flawed. It operated as intended most of the time, but there were easily exploitable loopholes within the programming that the average gamer could stumble across and eventually foster to create an unintended experience.</p>

<p>As a further example, Pokemon Red was programmed within the bounds of the popular game Minecraft, glitches and all: YouTube exploration (<span data-youtube="youtube-H-U96W89Z90?autoplay=1"><a rel="nofollow" href="https://www.youtube.com/watch?v=H-U96W89Z90"><img src="https://img.youtube.com/vi/H-U96W89Z90/0.jpg" width="640" height="385" border="0" alt="image" /></a></span>) and file (<a href="http://www.mediafire.com/file/cbu7gb2p1pbb4cv/Pokemon_Red_-_by_MrSquishy.zip/file" rel="nofollow">http://www.mediafire.com/file/cbu7gb2p1pbb4cv/Pokemon_Red_-_by_MrSquishy.zip/file</a>). For one, to explore code visually and spatially is amazing (that's a separate topic that I'd like to explore in the future), but the glitches became synonymous with the game. Numerous projects have "patched out" aspects of the game for a more unified experience, but something about it feels..."inauthentic," to borrow a rather disliked and problematic term. The glitch wasn't necessarily beyond the scope of the game: it WAS the game. It was built into the very foundation of the experience; how could it be bad?</p>

<p>As I'm still learning to explore coding, and given the growing but limited support for looking at code from earlier consoles and games, I don't have specific snippets to share from the Pokemon series (though it can be downloaded and played with at your leisure). However, I want to explore ideas of "embracing the glitch," in a way, through developing games. Many contemporary games have employed "glitches" to a degree, though many of these are programmed and very much intended (thinking about the "Doki Doki Literature Club" game; suicide/gore warning to those interested in playing), but glitches, in a broader fashion: could programming practices be made to embrace these ghostly areas of programming? Does "clean coding" and more hierarchical thinking, when it comes to coding, smooth out some of the wrinkles that may prompt later users to play with and explore unintended sides of a gaming experience? Is an intended glitch still a glitch?</p>

<p>I have more thoughts, but I want to leave it here for now.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Alice as a Victorian girl and Priscilla as an independent business woman</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/73/code-critique-alice-as-a-victorian-girl-and-priscilla-as-an-independent-business-woman</link>
        <pubDate>Wed, 29 Jan 2020 17:46:34 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>francesvanscoy</dc:creator>
        <guid isPermaLink="false">73@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title:TTLG (Code Critique)<br />
Author/s: Frances Van Scoy<br />
Language/s: Inform 7<br />
Year/s of development:2008-2020<br />
Software/hardware requirements: Mac OS 10.13.5; Inform 7 Build 6M62</p>

<pre><code>&quot;Kudzu Ken 20200127 v2&quot; by Frances Van Scoy



Book 2 - General Definitions

Use the serial comma.
Use American dialect.

When play begins:
    Say &quot;This game is one square of a planned 64 square mildly educational game set in the expanded world of Lewis Carroll's [italic type] Through the Looking Glass[roman type].  The anticipated main audience is middle school girls. [paragraph break] [paragraph break]&quot;;
    Say &quot;To the west you see a large brick wall with a wooden gate in it. You open the wooden gate and walk through it.  The gate closes behind you.&quot;;
    Now the likeability of the player is 2; [Likeability ranges from -5 to +5.]
    Now the left hand status line is &quot;[player's surroundings]&quot;;
    Now the right hand status line is &quot;Likeability: [likeability of the player]&quot;.

Part 3 - Properties of Things

A knapsack is a container.  A knapsack is wearable. 

Part 1 - Properties of Plants

A person can be known or unknown.

A plant is a kind of person.

A flower is a kind of plant. 

A daisy is a kind of flower.  

A tiger lily is a kind of flower. 

A weed is a kind of plant.

A kudzu_plant is a kind of weed.  The description of a kudzu_plant is &quot;The kudzu seems to be growing as you look at it.&quot;
A kudzu_plant is either quiet or active.  A kudzu_plant is usually quiet.
A kudzu_plant is either angry or defeated.  A kudzu_plant is usually angry.
kudzu is a kudzu_plant.

A tree is a kind of plant.

A dogwood is a kind of tree. The description of a dogwood is &quot;Next to the dogwood tree is a sign that says 'cornus florida.'&quot;  

Part 2 - Properties of Player Character

The player has a number called the likeability.

A person is either hostile_to_kudzu or friendly_to_kudzu.
A person is usually friendly_to_kudzu.

The player is wearing a knapsack.  The description of the knapsack is &quot;a canvas bag in which you store items you acquire.&quot;

A knife is in the knapsack.  The description of the knife is &quot;a garden knife, suitable for cutting an ear of corn from a cornstalk, for example&quot;.

Part 3 - Properties of Non Player Characters

Chapter 1 - Guard Dog Wood (a dogwood tree)

Guard Dog Wood is a tree. The description of Guard Dog Wood is &quot;Guard Dog Wood is an exceptionally large dogwood tree in the middle of the garden.&quot; 

Chapter 3 - Dayzee (a daisy)

Dayzee is a flower.  Dayzee is nowhere. 

Chapter 4 - Tigra (a tiger lily)

Tigra is a  flower. Tigra is nowhere.

Chapter 5 - Ken (a kudzu plant)

Ken is a kudzu_plant.  Ken is nowhere.  The printed name of Ken is &quot;a large aggressive kudzu plant&quot;.

Part 4 - Facts

A fact is a kind of thing. A fact can be known or unknown. A fact is usually unknown.

Flowers can talk is a fact.

Part 6 - Actions

Understand the command &quot;pick&quot; as something new.
Understand the command &quot;pick&quot; as &quot;take&quot;.

Understand &quot;who&quot; as whoing.
Whoing is an action applying to nothing.

Understand &quot;tickle&quot; as tickling.
Tickling is an action applying to nothing.

Understand &quot;help&quot; as helping.
Helping is an action applying to nothing.

Understand &quot;what&quot; as whating.
Whating is an action applying to nothing.

Book 3 - Scenes and Rooms

The player is in the Garden of Live Flowers.

Part 1 - The Scenes

Chapter 1 - Scene Main Garden

Main Garden is a scene.
Main Garden begins when play begins.

When Main Garden begins:
    if Guard Dog Wood is known:
        now Guard Dog Wood is in The Garden of Live Flowers;
    otherwise:
        now Guard Dog Wood is nowhere;
    if Tigra is known:
        now Tigra is in The Garden of Live Flowers;
    otherwise:
        now Tigra is nowhere;

Chapter 2 - Scene  Attack of the Creeper

Attack of the Creeper is a scene.

When Attack of the Creeper begins:
    say &quot;You feel something moving on your leg.  You look and see that a tendril of a kudzu plant is growing rapidly and wrapping itself around your leg.  Almost immediately it reaches your body and begins wrapping itself around you.&quot;; 
    now Ken is in the Garden of Live Flowers.

Attack of the Creeper ends badly when Ken is active and Ken is angry.

When Attack of the Creeper ends badly:
    say &quot;The kudzu lets out a horrifying scream, releases its grasp on you and grows to three times its previous size.&quot;

Attack of the Creeper ends well when  Ken is defeated.

When Attack of the Creeper ends well:
    Now Ken is in The Garden of Vegetables;
    Now Ken is quiet;
    say &quot;The kudzu struggles for a moment, uproots itself, crawls across the garden, and slides under the gate leading into the Garden of Vegetables    .&quot;

Section 1 - CUTTING a weed

Instead of taking a weed when Attack of the Creeper is happening:
    say &quot;You reach for the kudzu but it moves away from your hand.&quot;

Instead of cutting a weed when Attack of the Creeper is happening:
    if player is carrying a knife:
        say &quot;You attempt to cut the kudzu with the knife.&quot;;
        now Ken is active;
        now Ken is angry;
    otherwise:
        say &quot;You need to hold a knife in order to cut kudzu.&quot;

Section 2 - - TICKLING a weed

instead of tickling when Attack of the Creeper is happening:
    say &quot;The kudzu shakes with laughtern so much that it releases his grip on you.&quot;;
    increase the  likeability of the player by 2;
    now Ken is active;
    now Ken is defeated;
    now Ken is in The Garden of Vegetables.


Section 3 - Asking for HELP

[Advice on persuasion isfrom Writin with Infrom, section 12.4 Persuasion, Infor 7 Build 6M62.]

Persuasion rule for asking someone to try helping during Attack of the Creeper:
    if the likeability of the player is greater than 0:
        Say &quot;[the person asked] says to the kudzu, 'Let go of her right now!'&quot;;
        if the person asked is Guard Dog Wood:              
            Say &quot;The kudzu releases you.&quot;;
            increase the  likeability of the player by 1;
            Now Ken is quiet;
            Now Ken is defeated;
            persuasion succeeds;
        otherwise:
            Say &quot;The kudzu appears to stick out its tongue at [the person asked] and wraps his tendrils more tightly around you.&quot;;
            Now Ken is active;
            Now Ken is angry;
    otherwise:
        persuasion fails.

Part 2 - The Rooms

Chapter 1 - Outside the Garden

Outside the Garden is a room.  &quot;To the west you see a large brick wall with a wooden gate in it.&quot;


Chapter 2 - The Garden of Live Flowers

The Garden of Live Flowers is a room.  The Garden of Live Flowers is west of Outside the Garden.  &quot;You are in a large walled flower garden. In the center of the garden is a large dogwood tree.  Surrounding the dogwood are many flowers, including  daisies and tiger lilies.   There is also some  kudzu growing in the garden.   [paragraph break] The wooden gate in the brick wall on the east leads to the outside world.  There is no handle on the garden side of the door.  [paragraph break]   You hear a voice say, 'Welcome to the Garden of Live Flowers.'&quot;

In The Garden of Live Flowers are some daisies.   The daisies are scenery.
In The Garden of Live Flowers are some tiger lilies.  The tiger lilies are scenery.

In the Garden of Live Flowers is some kudzu.  The kudzu is scenery.

In the Garden of Live Flowers is a dogwood.  The dogwood is scenery.



Section 1 - GOING east, south, west or north

instead of going east when the player is in the Garden of Live Flowers:
        say &quot;The wooden gate in the brick wall leads to the outside world.  Unfortunately it only opens into the garden, and there is no handle on the garden side of the door.&quot; 

before going south:
    say &quot;This garden gate leads to the Garden of Vegetables.  You enter the garden and look around.   [if Ken is in Garden of Vegetables]You notice some kudzu is growing in this garden.[end if]&quot;;
    continue the action.

instead of going west when the player is in the Garden of Live Flowers:
        say &quot;That part of the world is still under construction.&quot;

instead of going north when the player is in the Garden of Live Flowers:
        say &quot;That part of the world is still under construction.&quot;

Section 3 - PICKING flowers

Instead of taking a flower  for the first time: 
        decrease the  likeability of the player by 1;
        say &quot;You think you hear  [the noun] screaming. Some nearby flowers shake, and you think you hear them saying something.  You hear a loud barking sound coming from the center of the garden.  You suddenly think that it might have been a bad idea to try to pick [the noun].&quot;;

Instead of taking a flower for the second time:
    decrease the  likeability of the player by 2;
    say &quot;You are startled by a noise from the center of the garden and release [the noun] without picking it.  You look up and see what appears to be an extremely rapidly growing branch coming from the dogwood tree in the middle of the garden.  It stops growing just above your head and then bends down, lifts you from the ground, shakes you and then drops you back onto the garden path.&quot;

Instead of taking a flower for at least the third time:
    decrease the likeability of the player by 3;
    say &quot;A large branch of the dogwood tree lifts you from the ground, extends itself over the brick wall, and drops you outside the garden.&quot;;
    move the player to Outside the Garden.

Instead of taking a kudzu for the first time:
    now the player is hostile_to_kudzu;
    say &quot;You attempt to pick the kudzu.&quot;.

Attack of the Creeper begins when the player is hostile_to_kudzu.

Section 4 - SAYING SORRY

Instead of saying sorry for the first time:
    increase the likeability of the player by 1;
    say &quot;You say, 'I'm awfully sorry!'&quot;.

Instead of saying sorry for at least the second time:
    say &quot;Apologizing over and over won't change anything!&quot;

Section 5 - WHOING (asking &quot;who&quot;)

Instead of whoing when player is in The Garden of Live Flowers and Guard Dog Wood is unknown :
    say &quot;'Who said that?' you ask. [paragraph break]'I did.  I am Guard Dog Wood.  I live in the Garden of Live Flowers and protect the plants in the garden.'&quot;;
    move Guard Dog Wood to the Garden of Live Flowers;
    now the printed name of Guard Dog Wood is &quot;Guard Dog Wood&quot;;
    now Guard Dog Wood is known.

Instead of whoing when player is in The Garden of Live Flowers and Guard Dog Wood is known and flowers can talk is unknown  :
    say &quot;'Who said that?' you ask. [paragraph break] 'I did.  My name's Tigra,' says a tall tiger lily as she bends gracefully towards you.  [paragraph break] 'I didn't know flowers could talk!' you say.  'I CAN talk,' says Tigra, 'when there's someone worth talking to.'  [paragraph break] 'We can ALL talk!' say several flowers simultaneously.'&quot;;
    move Tigra to the Garden of Live Flowers;
    now flowers can talk is known.


Section 7 - Recognizing speech that contains certain words

[The code in this section is based on Chapter 17 Understanding in Wriitng in  Inform in Build 6M62 of Inform 7 internal documentation. ]


After reading a command:
    if the player's command includes &quot;beauty&quot;:
        say &quot;You hear a voice saying 'Thank you!  We think the garden is a beautiful place to live.'&quot;;
        reject the player's command;
    if the player's command includes &quot;beautiful&quot;:
        say &quot;You hear a voice saying 'Thank you!  We think the garden is a beautiful place to live.'&quot;;
        reject the player's command;
    continue the action.

Chapter 4 - The Garden of Vegetables

The Garden of Vegetables is south from the Garden of Live Flowers.

Book 4 - Ending the game

check quitting the game:
    end the story;

When play ends:
    if the story has not ended finally:
        say &quot;Thanks for playing!  For more information about the game, please send email to LookingGlass@juno.com&quot;

Book 5 - Testing

test pick_plant with &quot;who / examine / look / pick daisy / pick daisy / pick daisy / west / pick kudzu /  tickle &quot;
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Week 1: amazon.html by Euguenio Tisselli</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/61/week-1-amazon-html-by-euguenio-tisselli</link>
        <pubDate>Mon, 20 Jan 2020 23:08:51 +0000</pubDate>
        <category>2020 Week 1: Introduction to Critical Code Studies</category>
        <dc:creator>jeremydouglass</dc:creator>
        <guid isPermaLink="false">61@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>by Mark C. Marino and Jeremy Douglass</p>

<blockquote><div>
  <p>In the <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/discussion/57/week-1-introduction-to-critical-code-studies-main-thread">Week 1 Introduction to Critical Code Studies</a> we mention Tisselli's piece amazon.html as an example of contemporary code as cultural discourse. Below is an overview and questions on amazon.html, presented in the form of a Working Group code critique for discussion.</p>
</div></blockquote>

<p><strong>Title</strong>: amazon.html<br />
<strong>By:</strong> Euguenio Tisselli<br />
<strong>Source:</strong> <a rel="nofollow" href="https://twitter.com/motorhueso/status/1157758552662040577">https://twitter.com/motorhueso/status/1157758552662040577</a><br />
<strong>Code:</strong> HTML/JavaScript<br />
<strong>Date:</strong> Aug. 3, 2019<br />
Released via Twitter</p>

<h3>Code:</h3>

<pre><code>&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset=&quot;utf-8&quot;&gt;&lt;title&gt;amazon&lt;/title&gt;&lt;style&gt;body{margin:0;overflow:hidden;}#x{text-align:center;padding-top:30px;}.p{line-height:0.3;display:block;}.q{font-size:2em;font-family:&quot;Courier&quot;;letter-spacing:-5px;}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div id=&quot;x&quot;&gt;&lt;/div&gt;
</code></pre>

<pre><code>&lt;script&gt;var s=5e3;var c=[&quot;#37ae3c&quot;,&quot;#236e12&quot;,&quot;#7bab2e&quot;];var x=document.getElementById(&quot;x&quot;);function g(y){return ~~(Math.random()*y);}var i=60;while(i--){var d=document.createElement(&quot;DIV&quot;);d.className=&quot;p&quot;;var j=50;while(j--){var t=document.createElement(&quot;SPAN&quot;);t.className=&quot;q&quot;;
</code></pre>

<pre><code>http://t.style.color=c[g(c.length)];t.textContent=&quot;*&quot;;d.appendChild(t);}x.appendChild(d);}function m(){var e=x.children[g(x.children.length)];var f=e.children[g(e.children.length)];http://f.style.color=&quot;#795548&quot;;f.textContent=String.fromCharCode(g(10)+48);
</code></pre>

<pre><code>s=s&gt;100?s-100:10;setTimeout(m,s);}setTimeout(m,s);&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;
</code></pre>

<p><br /></p>

<h3>Overview</h3>

<p>On August 3rd, 2019, Euguenio Tisselli posted “amazon.html”: a series of four plaintext code fragments of HTML with embedded JavaScript, all published as a single Twitter thread,[<sup><a rel="nofollow" href="#fn:1">1</a></sup>] along with instructions:</p>

<blockquote><div>
  <p>copy the following code (all of it, follow the thread), paste it on a plain text editor, save it as 'amazon.html', double click on the file so it shows in your browser... and watch <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%23capitalocene&amp;Mode=like">#capitalocene</a> unfold before your eyes!<br />
   <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%23visual&amp;Mode=like">#visual</a> <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%23code&amp;Mode=like">#code</a> <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/search&amp;Search=%23poetry&amp;Mode=like">#poetry</a><br />
  </p><div data-tweeturl="https://twitter.com/motorhueso/status/1157758552662040577" data-tweetid="1157758552662040577"><a href="https://twitter.com/motorhueso/status/1157758552662040577" rel="nofollow">https://twitter.com/motorhueso/status/1157758552662040577</a></div>
</div></blockquote>

<p>Individually, each fragment does nothing. When one does assemble the fragments and run amazon.html in a contemporary web browser[<sup><a rel="nofollow" href="#fn:2">2</a></sup>] the result is a large field of hundreds of asterisk characters of varying shades of green, evoking map or satellite view of a forest. Very slowly, green characters are replaced with brown numerals. Over time the process accelerates, until only a field of shifting numbers remains.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/94/kym1zqz6tnym.png" alt="Initial state of amazon script, all green asterisks" title="" /> <img src="http://wg20.criticalcodestudies.com/uploads/editor/wu/jr223d8rvh5i.png" alt="Intermediate state, green asterisks with mixed brown numerals" title="" /> <img src="http://wg20.criticalcodestudies.com/uploads/editor/y4/efdeqxgc2a7g.png" alt="Final state, all brown numerals" title="" /></p>

<p>In his tweet thread, Tisselli also linked to a page where “you can see it live” (<a href="http://motorhueso.net/amazon/" rel="nofollow">http://motorhueso.net/amazon/</a>), however that page also did not present the running code. Instead, it offered the same code as a single text block of HTML with embedded JavaScript (a one-liner, in fact, labeled “length: 873 bytes”) along with similar instructions to cut, paste, save, and run.[<sup><a rel="nofollow" href="#fn:3">3</a></sup>] The reader is asked to do this in order to witness what the code performs.[<sup><a rel="nofollow" href="#fn:4">4</a></sup>]</p>

<p>Both sources (the Twitter thread and the hosting webpage) contain similar commentaries on contexts of meaning for amazon.html. The thread contains a photo of Amazon rainforest clearcutting, along with a quote on the “tipping point” of deforestation; the webpage simply links to the source 2019 EcoWatch article “<a rel="nofollow" href="https://www.ecowatch.com/amazon-deforestation-unrecoverable-tipping-point-2639358982.html?rebelltitem=1#rebelltitem1">Amazon Deforestation Rate Hits 3 Football Fields Per Minute, Data Confirms</a>” while providing additional artist’s commentary on what it means to “watch the capitalocene unfold before your eyes” -- and on the role of algorithm and code in the piece.</p>

<blockquote><div>
  <p>what is destroying the forest? it is the capitalist algorithm, executed by <a rel="nofollow" href="https://www.ecowatch.com/amazon-deforestation-unrecoverable-tipping-point-2639358982.html?rebelltitem=1#rebelltitem1">fascist war-men/machines</a>. remove the algorithm from bodies and minds, smash the killer machines!</p>
  
  <p>code is the vector that transforms your desires into data // code extracts desires from your body, delivers them to the machine, and transports them through the full stack // code is what connects your infinite boredom to the tragedy of burning forests</p>
</div></blockquote>

<p>Due to the nature of the piece, the code is available in three forms: as fragments, as a one-liner, and as a user-generated file necessary for the piece to run. In all cases, the code is pre-minified or compressed, as is common in both commercial HTML+JavaScript and in aesthetic code art / play practices such as quines, esoteric languages, and code golf. An interesting aspect of this minification is that it is unlikely (although not impossible) that Tisselli actually composed or revised the code in this form. Instead, there might be (or might have been) an original author’s source code that was later minified before being published. <strong>[Edit: In fact, the code <em>was</em> authored in minified form.]</strong></p>

<p>Minified code, however, may be difficult to read (and annotate). It can largely be reversed by running it through parsers to add white space and unpack dense structures for each of the three syntax types in the document: HTML, CSS, and JavaScript. [<sup><a rel="nofollow" href="#fn:5">5</a></sup>] A resulting decompressed form of amazon.html looks like this:</p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;title&gt;
      amazon
    &lt;/title&gt;
    &lt;style&gt;
      body {
        margin: 0;
        overflow: hidden;
      }
      #x {
        text-align: center;
        padding-top: 30px;
      }
      .p {
        line-height: 0.3;
        display: block;
      }
      .q {
        font-size: 2em;
        font-family: &quot;Courier&quot;;
        letter-spacing: -5px;}
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;x&quot;&gt;&lt;/div&gt;
    &lt;script&gt;
      var s = 5e3;
      var c = [&quot;#37ae3c&quot;, &quot;#236e12&quot;, &quot;#7bab2e&quot;];
      var x = document.getElementById(&quot;x&quot;);
      function g(y) {
          return ~~(Math.random() * y);
      }
      var i = 60;
      while (i--) {
          var d = document.createElement(&quot;DIV&quot;);
          d.className = &quot;p&quot;;
          var j = 50;
          while (j--) {
              var t = document.createElement(&quot;SPAN&quot;);
              t.className = &quot;q&quot;;
              t.style.color = c[g(c.length)];
              t.textContent = &quot;*&quot;;
              d.appendChild(t);
          }
          x.appendChild(d);
      }
      function m() {
          var e = x.children[g(x.children.length)];
          var f = e.children[g(e.children.length)];
          f.style.color = &quot;#795548&quot;;
          f.textContent = String.fromCharCode(g(10) + 48);
          s = s &gt; 100 ? s - 100 : 10;
          setTimeout(m, s);
      }
      setTimeout(m, s);
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p><br /></p>

<h3>Questions for Discussion</h3>

<p>How to approach such code, and what to ask about it?</p>

<ul>
<li>We could question its form of representation and related idioms (ASCII art, helicopter and satellite photography, et cetera).</li>
<li>We could what it is and does -- is it random, is it interactive, does it change continuously or in stages, what is its model and/or what is it modeling, et cetera.</li>
<li>We could talk about its aesthetics -- at run time, in its presentation, and in the way it was coded / composed.</li>
<li>We could consider its intertextual references -- the related EcoWatch and Guardian articles, as well as whether its form is inspired by, an homage to, or borrowed / taken ready-made from other prior code.</li>
<li>We might consider it in the context of other work by Tisselli, or other discourse on the capitaloscene.</li>
<li>We could investigate about the relationships between the processes the user must perform to run the code and the code processes.</li>
<li>We could consider audience and platform: for example, can amazon.html be composited, saved, and loaded easily on a contemporary smartphone, or is it primarily accessible only to laptop users, and if so how does that relate to its dissemination through Twitter?</li>
<li>We might also consider questions of preservation, archiving, and dissemination. If this piece is worth talking about, is it worth keeping accessible three years, ten years, or fifty years from now? What would that accessibility look like, and what do the roles of artists, commentators, or scholars look like in that process?</li>
<li>Finally, what might any of this tell us about how amazon.html relates to the Amazon rainforest, deforestation, the capitaloscene, or algorithmic culture more broadly?</li>
</ul>

<blockquote><div>
  <p><img src="http://wg20.criticalcodestudies.com/uploads/editor/9a/qfyf1zbuc0je.png" alt="Aerial shot of Amazon rainforest with large clearcut section area on right half." title="" /><br />
  Amazon rainforest clearcutting photo tweeted by Tiisselli.</p>
</div></blockquote>

<p><br /><br /></p>

<div>
<hr />
<ol>

<li>
<p>A screenshot of the original Twitter thread: <a rel="nofollow" href="https://drive.google.com/file/d/1GTkQ82C0YxMyRn-V8lC51VmSn3FTB9VH/view?usp=sharing">https://drive.google.com/file/d/1GTkQ82C0YxMyRn-V8lC51VmSn3FTB9VH/view?usp=sharing</a>&#160;<a rel="nofollow" href="#fnref:1">&#8617;&#xfe0e;</a></p>
</li>

<li>
<p>Tested Jan 2019 on Chrome 79.0&#160;<a rel="nofollow" href="#fnref:2">&#8617;&#xfe0e;</a></p>
</li>

<li>
<p>A screenshot of the original webpage: <a rel="nofollow" href="https://drive.google.com/open?id=1iNV94bE3R1973rrTW7Gfx20zpI_vYcSz">https://drive.google.com/open?id=1iNV94bE3R1973rrTW7Gfx20zpI_vYcSz</a>&#160;<a rel="nofollow" href="#fnref:3">&#8617;&#xfe0e;</a></p>
</li>

<li>
<p>A running copy of the work: <a rel="nofollow" href="http://wg20.criticalcodestudies.com/files/amazon.html">http://wg20.criticalcodestudies.com/files/amazon.html</a>&#160;<a rel="nofollow" href="#fnref:4">&#8617;&#xfe0e;</a></p>
</li>

<li>
<p>Unminifying can be done using a programming text editor, such as TextMate, or using a web service, such as unminify.com -- both give similar identical results.&#160;<a rel="nofollow" href="#fnref:5">&#8617;&#xfe0e;</a></p>
</li>

</ol>
</div>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Livecoding Visuals with Hydra</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/86/code-critique-livecoding-visuals-with-hydra</link>
        <pubDate>Mon, 03 Feb 2020 15:42:44 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>mncmncmnc</dc:creator>
        <guid isPermaLink="false">86@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>I wanted to post a couple examples from languages that have been developed specifically for livecoding- the act of creating music and visuals with code in front of a live audience.</p>

<p>So here is an example of Hydra, a JavaScript-based language for visuals developed by <a rel="nofollow" href="https://ojack.github.io/" title="Olivia Jack">Olivia Jack</a> which does a wonderful job imitating old school multichannel video synthesis. This was written <a rel="nofollow" href="https://flordefuego.github.io/" title="by Flor De Fuego">by Flor De Fuego</a>. Its result can be run <a rel="nofollow" href="https://hydra-editor.glitch.me/" title="here">here</a> (which remains editable in browser).</p>

<p>•   Title: Let The Chaos Rule the Rest<br />
•   Author: Flor De Fuego<br />
•   Language: Hydra (authored by Olivia Jack)<br />
•   Year: 2019</p>

<pre><code>    //Flor de Fuego 
    osc(300,0.1) .contrast(3) .diff(osc(3000,0.1).rotate(5),1) .modulateScale(osc(3,0.1).kaleid(200),-0.9) 
    .modulateScale(osc(6,0.1).rotate(11).kaleid(-200),0.5) .mult(osc(1,0).kaleid(200).scrollX(0.1).scrollY(-0.1),0.8) 
    .blend(shape(200,0.01).scale(0.5,0.5).color(1,0,0) 
    .add(shape(4,0.1).color(1,0,0).scale(0.5,0.5).scrollX(()=&gt;Math.sin(1*time)*0.26),1).rotate(0,0.8) 
    .add(shape(200,0.1).scale(0.5,0.5).scrollX(()=&gt;Math.sin(1*time)*-0.47).color(0,0,1),1),0.5).rotate(0,0.5) 
    .mult(shape(200,0.01).scale(0.5,0.5) 
    .add(shape(4,0.1).color(1,0.5,1).scale(0.5,0.5).scrollX(()=&gt;Math.sin(1*time)*0.26),1).rotate(0,0.8) 
    .add(shape(200,0.1).scale(0.5,0.5).scrollX(()=&gt;Math.sin(1*time)*-0.47),1)).rotate(0,0.5) 
    //.color(1,[0,1],[0,1]) .rotate(0,0.8) .modulateRotate(osc(2),-1) .saturate([3,4,5,6,10].fast(8))
.diff(src(o0).modulateScale(osc(()=&gt;Math.sin(1*time)*20,0.5),0.03).scrollX(()=&gt;Math.sin(1*time)*0.001).scrollY(()=&gt;Math.sin(1*time)*-0.001)) .modulate(o0,()=&gt;Math.sin(1*time)*0.0001) .mult(shape(4,1).scrollY(-1).modulateScale(osc(3,0.5),-0.5)) .luma(0.1) //.add(src(o0).scrollX(0.01),0.001) //.mult(src(o0),0.01) //.luma(2) .out()
</code></pre>

<p>Here is another example, written by Flor and Zach Krall in collaboration. Its result can be seen <a rel="nofollow" href="https://hydra-editor.glitch.me/?sketch_id=b8M0juHHJoTJ0c9r&amp;code=JTJGJTJGRmxvciUyMGRlJTIwZnVlZ28lMjAlMjYlMjBaYWNrJTIwS3JhbGwlMjAlMEElMEFvc2MoOCUyQy0wLjEpLmNvbG9yKDElMkMxJTJDMS4zKS5zY3JvbGxZKDElMkMwLjEpJTBBLm1vZHVsYXRlKG9zYygxMCUyQzAuNSkubW9kdWxhdGUobm9pc2UoMikpKSUwQS5tb2R1bGF0ZShub2lzZSgyMCUyQy0xKSklMEEubW9kdWxhdGVSb3RhdGUobm9pc2UoMTAlMkMwLjEpKSUwQS5tb2R1bGF0ZShvc2MoOCUyQzAuMSklMEEubW9kdWxhdGUobm9pc2UoMikpKS5tb2R1bGF0ZShvMCUyQzAuMDUpJTBBLm1vZHVsYXRlKG8xJTJDMSkub3V0KCklMEFub2lzZSgzJTJDMC4xKS5tb2R1bGF0ZShub2lzZSgxKSUyQzEpJTBBLmNvbnRyYXN0KDUpLm1vZHVsYXRlUm90YXRlKG8xKSUwQS5tb2R1bGF0ZShvMSUyQzEpLm91dChvMSk=" title="here">here</a> (which remains editable in browser).</p>

<p>•   Untitled<br />
•   Authors: Flor De Fuego and Zach Krall<br />
•   Language: Hydra (authored by Olivia Jack)<br />
•   Year: 2019</p>

<pre><code>                osc(8,-0.1).color(1,1,1.3).scrollY(1,0.1)
                .modulate(osc(10,0.5).modulate(noise(2)))
                .modulate(noise(20,-1))
                .modulateRotate(noise(10,0.1))
                .modulate(osc(8,0.1)
                .modulate(noise(2))).modulate(o0,0.05)
                .modulate(o1,1).out()
                noise(3,0.1).modulate(noise(1),1)
                .contrast(5).modulateRotate(o1)
                .modulate(o1,1).out(o1)
</code></pre>

<p>I'd be happy to to discuss the ins and outs of the code (here is the <a rel="nofollow" href="https://github.com/ojack/hydra" title="Hydra Github">Hydra Github</a> and <a rel="nofollow" href="https://github.com/ojack/hydra/blob/master/docs/funcs.md" title="master function list">master function list</a>), but wanted to mention a couple ancillary thoughts-</p>

<p>One of my favorite things about Hydra is the upload button in the web-based version, which sends whatever you’re working on to the Hydra Patterns Twitter Bot, where then anyone in the world can click, and then edit your code, and then publish their version based on yours, all with attribution. I have never met Flor in-person, whose code is above, yet this language brought us together. Likewise, Zach and Flor collaborated on this code across thousands of miles without having yet met in-person.</p>

<p>This is a little bit of a personal aside, but as I’ve become a participant in the livecode/algorave scene, one of my favorite things about it has been an emerging political context, particularly among audience members. Several times I’ve met “disaffected tech workers” who wanted to come see livecoding to “see what could be created with the same tools” that aren’t in the service of big corporate tech. As a programmer who had just left Facebook recently said to me at a recent show “I’d rather create algorithms that make people dance than chase the monetization of data to political and social destruction.”</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: "Realitycraft: an RPG Rulesmithing Game"</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/78/code-critique-realitycraft-an-rpg-rulesmithing-game</link>
        <pubDate>Sun, 02 Feb 2020 21:10:04 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>shsteele</dc:creator>
        <guid isPermaLink="false">78@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Realitycraft: an RPG Rulesmithing Game</p>

<p>Author: Samara Hayley Steele</p>

<p>Language: RPG Code / Development Practice</p>

<p>Year/s of development: 2018-2019</p>

<p>About: A number of analog RPGs may be thought of as <a rel="nofollow" href="http://ijrp.subcultures.nl/wp-content/uploads/2016/12/IJRP-7-Steele.pdf" title="code that runs on humans">code that runs on humans</a>. The goal of this project is to create an environment in which players/users co-create analog code and run it.</p>

<p>Software/hardware/wetware requirements:</p>

<ul>
<li>Humans. Minimum of 3 players. Works best with around 20. You probably don't want to go much higher than 50.</li>
<li>Notecards</li>
<li>Sticky Notes (aka "Post-it Notes")</li>
<li>Pencils</li>
<li>(optional) 3-10 black masks.  If no black masks are available, matching capes could also work.</li>
<li>(optional) An hour glass with about 1-2 minutes worth of sand</li>
<li>Random Objects (for example):

<ol>
<li>a drum</li>
<li>a pair of sunglasses</li>
<li>a pile of 3-10 ambiguously shaped felt scapes (felt is a type of cloth), preferably large enough to stand on</li>
</ol></li>
</ul>

<pre><code>Warm up (3-5 min):

&quot;Hello everyone! I would like to invite you all to play a rulesmithing game.&quot;
Go around the room and give each player 2 sticky notes, 1 notecard, and distribute pencils.

&quot;First I would like you all to write a gender neutral noun on your notecard. It can be any noun, just be sure to pick one that is gender neutral.&quot; 

Once they have thought up and written down their gender neutral nouns, ask them to write the same noun on one of their sticky notes.  

Next, ask them to use their remaining sticky note to draw a room. &quot;It can be any room. Any type of room that you might find in a building.  A kitchen or a bathroom or a library or a lobby.  Any type of room is okay.&quot; 

Give them a minute or so to draw their rooms.

Now, ask them to walk around whatever space you are in, and have them place their room somewhere. Some of them might put their room on a wall.  Others might put it on a the floor.  Everywhere is okay.

Next, ask them all to hand you their notecards. (The notecards should by now each have a gender neutral-noun written on them.)

Now, ask them to place the remaining sticky note (which should have the same noun on it) on their chests.

Rulesmithing (4 min):

Break everyone into 2-3 groups of roughly the same size

Take your Random Objects (for example, a drum, a pair of sunglasses, a pile of felt scrapes) and place them on the ground. Be sure there's about 4 strides of space between each pile.

Assign each group to one of the piles. 

&quot;Your job, as a group is to figure out what this thing, or pile of things, does.  For example, maybe when I touch this drum, it lets me fly. Or makes me invisible. Or... you get the idea.&quot;

Have them work together to figure out what their group's object (or pile) does. Be sure to give them a 1-minute warning to wrap up.

Teaching Each Other the Rules (5 min):

&quot;All right. We're going to teach each other the rules we've just made.&quot; 

Have each group demo their rule to the rest of the group. Then, have everyone in the group try try the rule out.  Make sure they each actually demonstrate that they get the rule. If they don't seem to be getting it, have the others help them.

If a rule seems like it won't get properly distributed, you may choose to step in and modify it. (For example, let's say a group creates a cool rule for a single pair of sunglasses. To make sure that one person doesn't hoard them once the game starts, you can bring out the hourglass and say &quot;A player may only wear the sunglasses for the length of time measured by this hourglass.  If you are wearing the sunglasses, be sure to hold hour glass and measure your time. Once the hour glass runs out, you have to put the sunglasses and hour glass on the ground and walk away from them.&quot;

Once everyone seems to have a good idea of how the rules/objects work, time to start the RPG (roleplaying game).

The RPG (7-20 min):

&quot;We are going to play a short game, in which we play characters in an alternate universe. Look at the sticky note on your chest: that is your character's name. 

&quot;We are in a place called &quot;The Institution.&quot; It is a very big place.  Remember that room you drew earlier? That room is part of the Institution. And your character is the leading expert about that room.&quot;

&quot;In a few minutes, we are going to get into character, and when I call your character's name, it will be their turn to guide everyone to their room and to tell them about it.&quot;

&quot;In the mean time, all the rules we have just created with these objects will be in effect. Be sure to help each other if someone has forgotten how the rules work.&quot;

&quot;Also, sometimes you'll hear me speak as a voice from the PA system. &quot;testing, testing&quot;&quot;

&quot;Everyone, look down at the sticky now on your chest. That is your character's name.&quot;

Time to start the game:

&quot;And now we're going to become our characters. Please get into character.&quot;

Use your PA voice to start the game. &quot;Welcome to the Instution. Today you will all be giving each other tours of your rooms.&quot; Grab a random note card from your pile ad read the name. &quot;[Name] will be offering the first room tour.&quot;

As they go, be sure they are using the rules they've created. It's okay if the tour is constantly being interrupted and derailed, as long as they are engaging with the rules they've designed.

Every few minutes, depending on how much time you have, use your &quot;PA system voice&quot; to call upon a new person over to guide everyone to their room and give a tour.

--Optional: Enter the Rule Enforcers (5-10 minutes)--

One they've gotten into a flow of using the rules, pause the game.

Ask: &quot;Who feels pretty confident that you understand how the rules work?&quot; (show of hands)

The first 2-7 hands that go up, give them a black mask.

&quot;Everyone who has a black mask on is now a Rule Enforcer. Your job is to scan the room and make sure that everyone else is following the rules properly.&quot;

&quot;Alright everyone, we are going to go back to playing.  The next tour should be given by...&quot;

When it is time for the game to end, use your &quot;PA announcer voice&quot; to make some sort of statement.  Perhaps, something darkly funny like: &quot;It is now time for the Institution to close.  You have all done very well today. Please relocate to your transport methods and vacate the premises or you will be vaporized by security. Repeat: Please relocate to your transport methods and vacate the premises or you will be vaporized by security.&quot;

Debrief (5-7 min):

&quot;All right everyone! The game is officially over. I need everyone to help out with clean up!&quot; Remind everyone we are out-of-character now. 

Ask everyone to help put the Random objects away and game items away.

Once the space has been restored to its normal/clean form, circle up for a short debrief.

</code></pre>

<p>Debrief questions:</p>

<ul>
<li>"What was the most interesting moment in the game for you? What was the most fun?"</li>
<li>"We just created a set of rules and wandered around in a reality in which they are supposedly real. But we all know they aren't real, because we created them together. How did it feel to be in that kind of space? Did the rules ever start to feel real? If so, what made them feel real?"</li>
<li>(If there were enforcers) "Did the game change once there were enforcers? Was there anything different about that part of the game for you?"</li>
<li>"Do you think there might be things in the actual so-called "real world" that aren't quite "real" as well? If so, what kinds of things do you suspect might be the result of a set of social agreements?" If you have a whiteboard, write down what they say. Types of things to include: <strong>gender</strong>, <strong>race</strong>, <strong>nature</strong>, <strong>the economy</strong>. "How are these things so-created? Let's talk through this."

<ol>
<li>"What kinds of objects do we treat as if they are these things?" (Examples might include "melanin in a person's skin" "genital configurations" "stock ticker numbers" "plants" "animals")(be sure to ask complicating questions like, "Is your pet dog part of nature? Why not?"  or "Is your elbow the thing that gives you gender? Why not?")</li>
<li>"What kinds of social practices are used to make sure everyone keeps treating these objects that way?"</li>
</ol></li>
</ul>

<p>"Thanks everyone!"</p>

<p><strong>Follow-up writing prompt:</strong></p>

<p>Today we created a set of social rules around a bunch of random objects. But in the "real world," objects are also used as the center pieces for a set of social rules. What's the different between the game we played today, and those social rules in the "real world"? Could we call those real world rules "a game"? Why or why not? What kinds of experiences have you had based on "real world" objects like these? Were they good experiences? Why or why not?</p>

<p><strong>Follow-up reading:</strong></p>

<ul>
<li><em>Dark Matters</em> "Introduction" by Simone Browne</li>
<li><em>The New Jim Code</em> by Ruha Benjamin</li>
<li><em>Gender Trouble</em> by Judith Bulter</li>
<li><em>Take Back the Economy</em> by J.K. Gisbon Graham</li>
<li>Any RPG rulebook, such as <em>Dungeons and Dragons</em> or something from the White Wolf series.</li>
<li>"Ideology and Ideological State Apparatuses" by Louis Althusser</li>
<li>"Reification" from <em>History and Class Consciousness</em> by György Lukács</li>
</ul>

<p><strong>Artist's Statement</strong></p>

<p>I have now performed “Realitycraft: an RGP Rulesmithing Game” twice, as part of mini-conferences for the UC Davis Performance Studies Department in Dec 2019, and as part of a workshop in late 2018.</p>

<p>My goal with this piece is to simultaneously offer a demonstration of what I call “RPG rulesmithing” or the act of creating <em>intradiegetic objects</em>, while also providing a demonstration of some basic tenants of the RPG medium.  With this piece, I also aim to offer a material intervention into the normalization of reified economy, gender, race, and other "non-fiction" diegetic systems that, at times, find themselves congealed into material objects.  Rulesmithing, and the adjacent theory of intradiegetic objects, draws upon and modifies certain theoretical investments of Judith Butler, Louis Althusser, J.K. Gibson-Graham, and Gerard Genette.</p>

<p>Rulesmithing, as method, aims to engender fluency in the co-creation of the mutually agreed upon conditions of narrative reality.  This mode of fluency I see as liberatory as it allows a re-enchantment of materialities that had previously been subjected to enclosure.  This is to say, the ultimate goal of this piece is to facilitate an environment in which participants are engaging in behaviors that might productively be compared to the craft of law, gender, race, and capital while likewise maintaining a focus upon the act of crafting, rather than allowing craft to be invisiblized.</p>

<p>Also, as a feature of this piece, I avoid evoking terms pertaining to specific sets of systematized asymmetrical power relations (capital, gender, race, etc) until the discussion after the piece has been performed. This is because these terms and concepts have been heavily politicized (by virtue of the very asymmetrical power relations that allows their reification to maintains veridicality) and thus may trigger feelings from lived power-relations that, if evoked, may lead participants to foreclose upon engaging with the piece before it begins.</p>

<p>Photographic Documentation (from Nov. 22, 2019 run):</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/24/pa7ti9fuu2u9.png" alt="" title="" /><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/aw/4p43kg3ivip2.png" alt="" title="" /><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/3h/kmlhgr1lu4r3.png" alt="" title="" /><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/sx/tz70g9j5qq1k.png" alt="" title="" /><br />
<img src="http://wg20.criticalcodestudies.com/uploads/editor/xz/es91m6ztsy5p.png" alt="" title="" /></p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Line 255 of Sea and Spar Between</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/75/code-critique-line-255-of-sea-and-spar-between</link>
        <pubDate>Fri, 31 Jan 2020 15:02:52 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>nickm</dc:creator>
        <guid isPermaLink="false">75@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Software: <a rel="nofollow" href="https://nickm.com/montfort_strickland/sea_and_spar_between/"><i>Sea and Spar Between</i></a> (digital poetry)<br />
Authors: Nick Montfort and Stephanie Strickland<br />
Language: HTML/CSS/JavaScript, prototyped in Python<br />
Year: 2010, <a rel="nofollow" href="https://nickm.com/montfort_strickland/sea_and_spar_between/"><i>cut to fit the toolspun course</i> edition</a> 2013<br />
Source file: <a href="https://nickm.com/montfort_strickland/sea_and_spar_between/sea_spar.js" rel="nofollow">https://nickm.com/montfort_strickland/sea_and_spar_between/sea_spar.js</a><br />
“How to Read <i>SaSB</i>” page: <a href="https://nickm.com/montfort_strickland/sea_and_spar_between/reading.html" rel="nofollow">https://nickm.com/montfort_strickland/sea_and_spar_between/reading.html</a><br />
Blog post about bug fix: <a href="https://nickm.com/post/2020/01/sea-and-spar-between-1-0-1/" rel="nofollow">https://nickm.com/post/2020/01/sea-and-spar-between-1-0-1/</a></p>

<p>Stephanie Strickland and I wrote of a specific part of the <i>Sea and Spar Between</i> code: “The following syllables, which were commonly used as words by either Melville or Dickinson, are combined by the generator into compound words.” This particular way of conflating Melville’s language with Dickinson’s was important to us. However, due to a programming error, it wasn’t being done. What was line 255 in version 1:</p>

<p><code>syllable.concat(melvilleSyllable);</code></p>

<p>does not accomplish the purpose of adding the Melville one-syllable words to the variable <code>syllable</code>, which holds an array of Dickinson’s words at this point. The concatenation happens, but the <code>concat()</code> method does not change the <code>syllable</code> array in place. The resulting longer list is simply thrown away. This line has been changed in version 1.0.1, published yesterday. The relevant line, because of the addition of explanatory comments, is now line 286:</p>

<p><code>syllable = syllable.concat(melvilleSyllable);</code></p>

<p>I noticed this omission myself only years after the 2013 publication of <i>cut to fit the toolspun course,</i> a richly commented edition of <i>Sea and Spar Between.</i> As a result of my mistake, the compound or kenning “toolspun,” used in the title of that work, never was actually produced in any existing version of <i>Sea and Spar Between.</i> This was a frustrating situation, but after Stephanie and I discussed it briefly, we decided that we would wait to consider releasing an updated version until this defect was discovered by someone else, such as a critic or translator.</p>

<p>The system has been translated to Polish and has been “remixed” once that we know of. The ELMCIP database <a rel="nofollow" href="https://elmcip.net/creative-work/sea-and-spar-between">lists 20 references to <i>Sea and Spar Between</i> in critical writing.</a></p>

<p>The defect was only discovered recently by a critic, Aaron Pinnix, a Fordham PhD student doing a dissertation on oceanic literary works.</p>

<p>The <i>cut to fit the toolspun course</i> edition of the project (incorrectly given the title “cut to fit the tool-spun course” in the journal <i>Digital Humanities Quarterly</i> when it was published) is less than 1000 lines long, not lengthy for an academic paper on electronic literature. This may be the most detailed discussion of a digital literary system’s code by the authors of that system.</p>

<p>Yet Pinnix discovered the mistake simply by carefully reading the system’s output and carefully reading statements that Strickland and I made about how the system was supposed to work; there was no tracing through the code and no CCS analysis done. It seems that a thorough and attentive traditional reading, in this case, led to the most complete understanding of how this system works so far.</p>
]]>
        </description>
    </item>
    <item>
        <title>A Travesty Generator for Micros</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/92/a-travesty-generator-for-micros</link>
        <pubDate>Tue, 04 Feb 2020 19:43:57 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>zachwhalen</dc:creator>
        <guid isPermaLink="false">92@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>As I mentioned in <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/discussion/comment/959/#Comment_959">a reply</a> to <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/profile/Leonardo.Flores">@Leonardo.Flores</a>'s code critique of some NaNoGenMo works, we can think of Hugh Kenner and Joseph O'Rourke's 1984 "Travesty" program as the ancestor of many other methods for generating text based on some source text. It's a common point of reference for discussions of computer-aided creativity (Charles Hartmann, for example, demonstrates it in <em>Virtual Muse</em>), and it's relatively easy to understand what it does.</p>

<p>Since Kenner and O'Rourke first shared Travesty by <a rel="nofollow" href="https://archive.org/details/byte-magazine-1984-11/page/n129/mode/2up">publishing it in <em>Byte Magazine</em></a>, I thought it would be interesting to take a closer look at what the code does. Does it demonstrate some ideas about the original text it works on? Since the term "travesty" is pretty dramatic, is there evidence in what it's doing that validates that idea of what it's doing to the text? Is what goes on in Travesty truly similar to processes that we think of as its descendants (Markov chain and char-rnn, mainly), or is something else at work?</p>

<p>Travesty is written in Pascal, a language I don't have any prior experience with. Still, getting it to run was pretty straightforward. I've transcribed it line by line (including comments) from <em>Byte</em> and shared it <a rel="nofollow" href="https://github.com/zachwhalen/travesty">in a Github repository</a>, along with some instructions on using it.</p>

<p>Since <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/discussion/53/how-to-post-a-code-critique#latest">the directions</a> say to post the code you're critiquing in your thread, I'll include it here as well. I'll post some initial thoughts in a reply to this thread.</p>

<hr />

<blockquote><div>
  <p><strong><a rel="nofollow" href="https://archive.org/details/byte-magazine-1984-11/page/n447/mode/2up">Listing 1</a>:</strong> <em>Travesty, a program for generating pseudo-text. The program will scan a sample text and generate a "nonsense" imitation. For an order-n scan, every n-character sequence in the output occurs somewhere in the input.</em></p>
</div></blockquote>

<pre><code>\n
\n
PROGRAM travesty (input,output);            { Kenner/ O'Rourke, 5/9/84}

(*     This is based on Brian Hayes' article in Scientific           *)
(*     American, November 1983. It scans a text and generates        *)
(*     an n-order simulation of its letter combinations. For         *)
(*     order n, the relation of output to input is exactly:          *)
(*           &quot;Any pattern n characters long in the output            *)
(*               has occurred somewhere in the input,                *)
(*                 and at about the same frequency.&quot;                 *)
(*     Input should be ready on disk. Program asks how many           *)
(*     characters of output you want. It next asks for the           *)
(*     &quot;Order&quot; -- i.e. how long a string of characters will be       *)
(*     cloned to output when found. You are asked for the            *)
(*     name of the input file, and offered a &quot;Verse&quot; option.         *)
(*     If you select this, and if the input has a &quot;|&quot; char-          *)
(*     acter at the end of each line, words that ends lines in       *)
(*     the original will terminate output lines. Otherwise,          *)
(*     output lines will average 50 characters in length.            *)

CONST 
  ArraySize = 3000;       {maximum number of text chars}
  MaxPat = 9;        {maximum Pattern length}

VAR
  BigArray : PACKED ARRAY [1..ArraySize] of CHAR;
  FreqArray, StartSkip : ARRAY[' '..'|'] of INTEGER;
  Pattern : PACKED ARRAY [1..MaxPat] of CHAR;
  SkipArray : ARRAY [1..ArraySize] of INTEGER;
  OutChars : INTEGER;    {number of characters to be output}
  PatLength : INTEGER;
  f : TEXT;
  CharCount : INTEGER; {characters so far output}
  Verse, NearEnd : BOOLEAN;
  NewChar : CHAR;
  TotalChars : INTEGER; {total chars input, + wraparound}
  Seed : INTEGER;

FUNCTION Random (VAR RandInt : INTEGER) : REAL;
BEGIN
  Random := RandInt / 1009;
  RandInt := (31 * RandInt + 11) MOD 1009
END;

PROCEDURE InParams;
  (* Obtains user's instructions *)
VAR
  InFile : STRING [12];
  Response : CHAR;
BEGIN
  WRITELN ('Enter a Seed (1..1000) for the randomizer');
  READLN (Seed);
  WRITELN ('Number of characters to be output?');
  READLN (OutChars);
  REPEAT
    WRITELN ('What order? &lt;2-', MaxPat,'&gt;');
    READLN (PatLength)
  UNTIL (PatLength IN [2..MaxPat]);
  PatLength := PatLength - 1;
  WRITELN ('Name of input file?');
  READLN (InFile);
  ASSIGN (f, InFile);
  RESET (f);
  WRITELN ('Prose or Verse? &lt;p/v&gt;');
  READLN (Response);
  IF (Response = 'V') OR (Response = 'v') THEN
    Verse := true
  ELSE Verse := false
END; {Procedure InParams}

PROCEDURE ClearFreq;
(*  FreqArray is indexed by 93 probable ASCII characters,            *)
(*  from &quot; &quot; to &quot;|&quot;. Its elements are all set to zero.               *)
VAR
  ch : CHAR;
BEGIN
  FOR ch := ' ' TO '|' DO
    FreqArray[ch] := 0
END; {Procedure ClearFreq}

PROCEDURE NullArrays;
(* Fill BigArray and Pattern with nulls *)
VAR
  j : INTEGER;
BEGIN
  FOR j := 1 TO ArraySize DO
    BigArray[j] := CHR(0);
  FOR j := 1 TO MaxPat DO
    Pattern[j] := CHR(0)
END; {Procedure NullArrays}

PROCEDURE FillArray;
(*    Moves textfile from disk into BigArray, cleaning it            *)
(*    up and reducing any run of blanks to one blank.                *)
(*    Then copies to end of array a string of its opening            *)
(*    characters as long as the Pattern, in effect wrapping          *)
(*    the end to the beginning.                                      *)
VAR
  Blank : BOOLEAN;
  ch: CHAR;
  j: INTEGER;

  PROCEDURE Cleanup;
  (* Clears Carriage Returns, Linefeeds, and Tabs out of            *)
  (* input stream. All are changed to blanks.                       *)
  BEGIN
    IF ((ch = CHR(13))     {CR}
      OR (ch = CHR(10))   {LF}
      OR (ch = CHR(9)))  {TAB}
    THEN ch := ' '
  END;

BEGIN {Procedure FillArray}
  j := 1;
  Blank := false;
  WHILE (NOT EOF(f)) AND ( j &lt;= (ArraySize - MaxPat)) DO
  BEGIN {While Not EOF}
    READ (f,ch);
    Cleanup;
    BigArray[j] := ch;                    {Place character in BigArray}
    IF ch = '' THEN Blank := true;
    j := j + 1;
    WHILE (Blank AND (NOT EOF(f))
      AND (j &lt;= (ArraySize - MaxPat))) DO
    BEGIN {While Blank}                    {When a blank has just been}
      READ (f,ch);                            {printed, Blank is true,}
      Cleanup;                      {so succeeding blanks are skipped,}
      IF ch &lt;&gt; '' THEN                            {thus stopping runs.}
      BEGIN {If}
        Blank := false;
        BigArray[j] := ch;                 {To BigArray if not a Blank}
        j := j + 1
      END {If}
    END {While Blank}
  END; {While Not EOF}
  TotalChars := j - 1;
  IF BigArray[TotalChars] &lt;&gt; '' THEN
  BEGIN   {If no Blank at end of text, append one}
    TotalChars := TotalChars + 1;
    BigArray[TotalChars] := ' '
  END;
  {Copy front of array to back to simulate wraparound.}
  FOR j := 1 TO PatLength DO
    BigArray[TotalChars + j] := BigArray[j];
  TotalChars := TotalChars + PatLength;
  WRITELN('Characters read, plus wraparound = ',TotalChars:4)
END; {Procedure FillArray}

PROCEDURE FirstPattern;
(* User selects &quot;order&quot; of operation, an integer, n, in the          *)
(* range 1 .. 9. The input text will henceforth be scanned           *)
(* in n-sized chunks. The first n-1 characters of the input          *)
(* file are placed in the &quot;Pattern&quot; Array. The Pattern is            *)
(* written at the head of output.                                    *)
VAR
  j : INTEGER;
BEGIN
  FOR j := 1 TO PatLength DO           {Put opening chars into Pattern}
    Pattern[j] := BigArray[j];
  CharCount := PatLength;
  NearEnd := false;
  IF Verse THEN WRITE (' ');   {Align first line}
  FOR j := 1 TO PatLength DO
    WRITE (Pattern[j])
  END; {Procedure FirstPattern}

PROCEDURE InitSkip;
(*   The i-th entry of SkipArray contains the smallest index         *)
(*   j &gt; i such that BigArray[j] = BigArray[i]. Thus SkipArray       *)
(*   links together all identical characters in BigArray.            *)
(*   StartSkip contains the index of the first occurrence of         *)
(*   each character. These two arrays are used to skip the           *)
(*   matching routine through the text, stopping only at             *)
(*   locations whose character matches the first character           *)
(*   in Pattern.                                                     *)
VAR
  ch : CHAR;
  j : INTEGER;
BEGIN
  FOR ch := ' ' TO '|' DO
    StartSkip[ch] := TotalChars + 1;
  FOR j := TotalChars DOWNTO 1 DO
  BEGIN
    ch := BigArray[j];
    SkipArray[j] := StartSkip[ch];
    StartSkip[ch] := j
  END
END; {Procedure InitSkip}

PROCEDURE Match;
(*   Checks BigArray for strings that match Pattern; for each        *)
(*   match found, notes following character and increments its       *)
(*   count in FreqArray. Position for first trial comes from         *)
(*   StartSkip; thereafter positions are taken from SkipArray.       *)
(*   Thus no sequence is checked unless its first character is       *)
(*   already known to match first character of Pattern.              *)
VAR
  i : INTEGER;     {one location before start of the match in BigArray}
  j : INTEGER; {index into Pattern}
  Found : BOOLEAN;      {true if there is a match from i+1 to i+j - 1 }
  ch1 : CHAR;       {the first character in Pattern; used for skipping}
  NxtCh : CHAR;
BEGIN {Procedure Match}
  ch1 := Pattern[1];
  i := StartSkip[ch1] - 1;         {is is 1 to left of the Match start}
  WHILE (i &lt;= TotalChars - PatLength - 1) DO
  BEGIN {While}
    j := 1;
    Found := true;
    WHILE (Found AND (j &lt;= PatLength)) DO
      IF BigArray[i+j] &lt;&gt; Pattern[j]
        THEN Found := false   {Go thru Pattern til Match fails}
        ELSE j := j + 1;
      IF Found THEN
      BEGIN            {Note next char and increment FreqArray}
        NxtCh := BigArray[i + PatLength + 1];
        FreqArray[NxtCh] := FreqArray[NxtCh] + 1
      END;
      i := SkipArray[i + 1] - 1  {Skip to next matching position}
    END {While}
  END; {Procedure Match}

PROCEDURE WriteCharacter;
(*   The next character is written. It is chosen at Random           *)
(*   from characters accumulated in FreqArray during last            *)
(*   scan of input. Output lines will average 50 character           *)
(*   in length. If &quot;Verse&quot; option has been selected, a new           *)
(*   line will commence after any word that ends with &quot;|&quot; in         *)
(*   input file. Thereafter lines will be indented until             *)
(*   the 50-character average has been made up.                      *)
VAR
  Counter, Total, Toss : INTEGER;
  ch : CHAR;
BEGIN
  Total := 0;
  FOR ch := ' ' TO '|' DO
  Total := Total + FreqArray[ch]; {Sum counts in FreqArray}
  Toss := TRUNC (Total * Random(Seed)) + 1;
  Counter := 31;
  REPEAT
    Counter := Counter + 1;                         {We begin with ' '}
    Toss := Toss - FreqArray[CHR(Counter)]
    until Toss &lt;= 0;                                   {Char chosen by}
  NewChar := CHR(Counter);                    {successive subtractions}
  IF NewChar &lt;&gt; '|' THEN
    WRITE (NewChar);
  CharCount := CharCount + 1;
  IF CharCount MOD 50 = 0 THEN NearEnd := true;
  IF ((Verse) AND (NewChar = '|')) THEN WRITELN;
  IF ((NearEnd) AND (NewChar = ' ')) THEN
  BEGIN {If NearEnd}
    WRITELN;
    IF Verse THEN WRITE ('     ');
    NearEnd := false
  END {If NearEnd}
END; {Procedure Write Character}

PROCEDURE NewPattern;
(*   This removes the first character of the Pattern and             *)
(*   appends the character just printed. FreqArray is                *)
(*   zeroed in preparation for a new scan.                           *)
VAR
  j : INTEGER;
BEGIN
  FOR j := 1 to PatLength - 1 DO
    Pattern[j] := Pattern[j + 1];             {Move all chars leftward}
  Pattern[PatLength] := NewChar;                       {Append NewChar}
  ClearFreq
END; {Procedure NewPattern}

BEGIN {Main Program}
  ClearFreq;
  NullArrays;
  InParams;
  FillArray;
  FirstPattern;
  InitSkip;
  REPEAT
    Match;
    WriteCharacter;
    NewPattern
  UNTIL CharCount &gt;= OutChars;
END. {Main Program}
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique:  RoundRects - Apple QuickDraw Source Code</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/80/code-critique-roundrects-apple-quickdraw-source-code</link>
        <pubDate>Mon, 03 Feb 2020 00:19:45 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>DavidBerry</dc:creator>
        <guid isPermaLink="false">80@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Bill Atkinson was a member of the original Macintosh development team.  He created Quickdraw first for the Lisa, as LisaGraf. Andy Hertzfeld, another key member of the team, considers QuickDraw “the single most significant component of the original Macintosh technology” in its ability to “push pixels around in the frame buffer at blinding speeds to create the celebrated user interface.”</p>

<p><strong>The Anecdote</strong></p>

<p>Bill Atkinson worked mostly at home, but whenever he made significant progress he rushed in to Apple to show it off to anyone who would appreciate it. This time, he visited the Macintosh offices at Texaco Towers to show off his brand new oval routines in Quickdraw, which were implemented using a really clever algorithm.</p>

<p>Bill had added new code to QuickDraw (which was still called LisaGraf at this point) to draw circles and ovals very quickly. That was a bit hard to do on the Macintosh, since the math for circles usually involved taking square roots, and the 68000 processor in the Lisa and Macintosh didn't support floating point operations. But Bill had come up with a clever way to do the circle calculation that only used addition and subtraction, not even multiplication or division, which the 68000 could do, but was kind of slow at.</p>

<p>Bill's technique used the fact the sum of a sequence of odd numbers is always the next perfect square (For example, 1 + 3 = 4, 1 + 3 + 5 = 9, 1 + 3 + 5 + 7 = 16, etc). So he could figure out when to bump the dependent coordinate value by iterating in a loop until a threshold was exceeded. This allowed QuickDraw to draw ovals very quickly.</p>

<p>Bill fired up his demo and it quickly filled the Lisa screen with randomly-sized ovals, faster than you thought was possible. But something was bothering Steve Jobs. "Well, circles and ovals are good, but how about drawing rectangles with rounded corners? Can we do that now, too?"</p>

<p>"No, there's no way to do that. In fact it would be really hard to do, and I don't think we really need it". I think Bill was a little miffed that Steve wasn't raving over the fast ovals and still wanted more.</p>

<p>Steve suddenly got more intense. "Rectangles with rounded corners are everywhere! Just look around this room!". And sure enough, there were lots of them, like the whiteboard and some of the desks and tables. Then he pointed out the window. "And look outside, there's even more, practically everywhere you look!". He even persuaded Bill to take a quick walk around the block with him, pointing out every rectangle with rounded corners that he could find.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/tx/mzh62hu2m47j.jpg" alt="" title="" /><br />
When Steve and Bill passed a no-parking sign with rounded corners, it did the trick. "OK, I give up", Bill pleaded. "I'll see if it's as hard as I thought." He went back home to work on it.</p>

<p>Bill returned to Texaco Towers the following afternoon, with a big smile on his face. His demo was now drawing rectangles with beautifully rounded corners blisteringly fast, almost at the speed of plain rectangles. When he added the code to LisaGraf, he named the new primitive "RoundRects". Over the next few months, roundrects worked their way into various parts of the user interface, and soon became indispensable.</p>

<p><strong>The Code</strong></p>

<p>Author: Bill Atkinson<br />
Year: 1981</p>

<p>QuickDraw is the Macintosh library for creating bit-mapped graphics, which was used by MacPaint and other applications. It consists of a total of 17,101 lines in 36 files, all written in assembler language for the 68000.</p>

<p>This is the RRects code which contains the functions for the new primitive "RoundRects". We now take these for granted in the Mac and iOS interfaces, but they started out here. I thought it would be interesting to try to deconstruct this code which is extremely tightly written to see if we can see the beginnings of a user interface primitive that has become so iconic (look at your display!). The <a rel="nofollow" href="https://d1yx3ys82bpsa0.cloudfront.net/102658076_quickdraw_acc.zip" title="full code for QuickDraw is here">full code for QuickDraw is here</a>.</p>

<pre><code>               .INCLUDE  GRAFTYPES.TEXT

;-----------------------------------------------------------
;
;
;     ****   ****   *****   ***   *****   ***
;     *   *  *   *  *      *   *    *    *   *
;     *   *  *   *  *      *        *    *
;     ****   ****   ***    *        *     ***
;     * *    * *    *      *        *        *
;     *  *   *  *   *      *   *    *    *   *
;     *   *  *   *  *****   ***     *     ***
;
;
;  procedures for operating on RoundRects.
;
;

    .PROC StdRRect,4
    .REF  CheckPic,DPutPicByte,PutPicVerb,PutPicLong,PutPicRect
    .REF  PutOval,PushVerb,DrawArc
;---------------------------------------------------------------
;
;  PROCEDURE StdRRect(verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER);
;
;  A6 OFFSETS OF PARAMS AFTER LINK:
;
PARAMSIZE       .EQU    10
VERB            .EQU    PARAMSIZE+8-2           ;GRAFVERB
RECT            .EQU    VERB-4                  ;LONG, ADDR OF RECT
OVWD            .EQU    RECT-2                  ;WORD
OVHT            .EQU    OVWD-2                  ;WORD

            LINK    A6,#0                           ;NO LOCALS
            MOVEM.L D7/A3-A4,-(SP)                  ;SAVE REGS
            MOVE.B  VERB(A6),D7                     ;GET VERB
            JSR     CHECKPIC                        ;SET UP A4,A3 AND CHECK PICSAVE
            BLE.S   NOTPIC                          ;BRANCH IF NOT PICSAVE

            MOVE.B  D7,-(SP)                        ;PUSH VERB
            JSR     PutPicVerb                      ;PUT ADDIONAL PARAMS TO THEPIC
;
;  CHECK FOR NEW OVAL SIZE
;
            MOVE.L  PICSAVE(A3),A0                  ;GET PICSAVE HANDLE
            MOVE.L  (A0),A0                         ;DE-REFERENCE PICSAVE
            MOVE.L  OVHT(A6),D0                     ;GET OVWD AND OVHT
            CMP.L   PICOVSIZE(A0),D0                ;SAME AS CURRENT OVAL SIZE ?
            BEQ.S   OVALOK                          ;YES, CONTINUE
            MOVE.L  D0,PICOVSIZE(A0)                ;NO, UPDATE STATE VARIABLE
            MOVE.L  D0,-(SP)                        ;PUSH OVSIZE FOR PutPicLong CALL
            MOVEQ   #$0B,D0
            JSR     DPutPicByte                     ;PUT OVSIZE OPCODE
            JSR     PutPicLong                      ;PUT NEW OVAL SIZE DATA

OVALOK  MOVEQ   #$40,D0                         ;PUT RRECT NOUN IN HI NIBBLE
            ADD     D7,D0                           ;PUT VERB IN LO NIBBLE
            MOVE.B  D0,-(SP)                        ;PUSH OPCODE
            MOVE.L  RECT(A6),-(SP)                  ;PUSH ADDR OF RECT
            JSR     PutPicRect                      ;PUT OPCODE AND RECTANGLE

NOTPIC  MOVE.L  RECT(A6),-(SP)                  ;PUSH ADDR OF RECT
            CLR.B   -(SP)                           ;PUSH HOLLOW = FALSE
            TST.B   D7                              ;IS VERB FRAME ?
            BNE.S   DOIT                            ;NO, CONTINUE
            TST.L   RGNSAVE(A3)                     ;YES, IS RGNSAVE TRUE ?
            BEQ.S   NOTRGN                          ;NO, CONTINUE

            MOVE.L  RECT(A6),-(SP)                  ;YES, PUSH ADDR OF RECT
            MOVE.L  OVHT(A6),-(SP)                  ;PUSH OVWD, OVHT
            MOVE.L  RGNBUF(A4),-(SP)                ;PUSH RGNBUF
            PEA     RGNINDEX(A4)                    ;PUSH VAR RGNINDEX
            PEA     RGNMAX(A4)                      ;PUSH VAR RGNMAX
            JSR     PutOval                         ;ADD AN OVAL TO THERGN

NOTRGN  MOVE.B  #1,(SP)                         ;REPLACE, PUSH HOLLOW = TRUE
DOIT    MOVE.L  OVHT(A6),-(SP)                  ;PUSH OVWD,OVHT
            JSR     PushVerb                        ;PUSH MODE AND PATTERN
            CLR     -(SP)                           ;PUSH STARTANGLE = 0
            MOVE    #360,-(SP)                      ;PUSH ARCANGLE = 360

;  DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng);

            JSR     DrawArc

            MOVEM.L (SP)+,D7/A3-A4                  ;RESTORE REGS
            UNLINK  PARAMSIZE,'STDRRECT'



            .PROC FrameRoundRect,3
            .DEF  CallRRect,PaintRoundRect,EraseRoundRect
            .DEF  InvertRoundRect,FillRoundRect
            .REF  StdRRect
;--------------------------------------------------------
;
;  PROCEDURE FrameRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
;
            MOVEQ   #FRAME,D0                       ;VERB = FRAME
            BRA.S   CallRRect                       ;SHARE COMMON CODE


;--------------------------------------------------------
;
;  PROCEDURE PaintRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
;
PaintRoundRect
            MOVEQ   #PAINT,D0                       ;VERB = PAINT
            BRA.S   CallRRect                       ;SHARE COMMON CODE


;--------------------------------------------------------
;
;  PROCEDURE EraseRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
;
EraseRoundRect
            MOVEQ   #ERASE,D0                       ;VERB = ERASE
            BRA.S   CallRRect                       ;SHARE COMMON CODE


;--------------------------------------------------------
;
;  PROCEDURE InvertRoundRect(* r: Rect; ovWd,ovHt: INTEGER *);
;
InvertRoundRect
            MOVEQ   #INVERT,D0                      ;VERB = INVERT
            BRA.S   CallRRect                       ;SHARE COMMON CODE


;--------------------------------------------------------
;
;  PROCEDURE FillRoundRect(r: Rect; ovWd,ovHt: INTEGER; pat: Pattern);
;
FillRoundRect
            MOVE.L  (SP)+,A0                        ;POP RETURN ADDR
            MOVE.L  (SP)+,A1                        ;POP ADDR OF PATTERN
            MOVE.L  A0,-(SP)                        ;PUT RETURN ADDR BACK
            MOVE.L  GRAFGLOBALS(A5),A0              ;POINT TO LISAGRAF GLOBALS
            MOVE.L  THEPORT(A0),A0                  ;GET CURRENT GRAFPORT
            LEA     FILLPAT(A0),A0                  ;POINT TO FILLPAT
            MOVE.L  (A1)+,(A0)+                     ;COPY PAT INTO FILLPAT
            MOVE.L  (A1)+,(A0)+                     ;ALL EIGHT BYTES
            MOVEQ   #FILL,D0                        ;VERB = FILL
            BRA.S   CallRRect                       ;SHARE COMMON CODE



;---------------------------------------------------------------
;
;  PROCEDURE CallRRect(r: Rect; ovWd,ovHt: INTEGER);
;
;  code shared by FrameRoundRect, PaintRoundRect, EraseRoundRect,
;                 InvertRoundRect, and FillRoundRect.
;  enter with verb in D0.
;
CallRRect
            MOVE.L  (SP)+,A0                        ;POP RETURN ADDR
            MOVE.L  (SP)+,D1                        ;POP ovWd and ovHt
            MOVE.L  (SP)+,A1                        ;POP ADDR OF RECT
            MOVE.B  D0,-(SP)                        ;PUSH VERB
            MOVE.L  A1,-(SP)                        ;PUSH ADDR OF RECT
            MOVE.L  D1,-(SP)                        ;PUSH ovWd and ovHt
            MOVE.L  A0,-(SP)                        ;RESTORE RETURN ADDR
            MOVE.L  GRAFGLOBALS(A5),A0              ;POINT TO LISAGRAF GLOBALS
            MOVE.L  THEPORT(A0),A0                  ;GET CURRENT GRAFPORT
            MOVE.L  GRAFPROCS(A0),D0                ;IS GRAFPROCS NIL ?
            LEA     STDRRECT,A0
            BEQ.S   USESTD                          ;YES, USE STD PROC
            MOVE.L  D0,A0
            MOVE.L  RRECTPROC(A0),A0                ;NO, GET PROC PTR
USESTD  JMP     (A0)                            ;GO TO IT





        .END
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique:  Mel, FIRESTARTER and Misreading Code</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/77/code-critique-mel-firestarter-and-misreading-code</link>
        <pubDate>Sun, 02 Feb 2020 07:16:22 +0000</pubDate>
        <category>2020 Week 2: Indigenous Programming</category>
        <dc:creator>barry.rountree</dc:creator>
        <guid isPermaLink="false">77@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Title:</strong>  FIRESTARTER<br />
<strong>Author:</strong>  Daniel Hackenberg et al.<br />
<strong>Languages:</strong>  Python, C, x86-64 assembly<br />
<strong>Date:</strong> 2013-<br />
<strong>Git repo:</strong>  <a rel="nofollow" href="https://github.com/tud-zih-energy/FIRESTARTER" title="https://github.com/tud-zih-energy/FIRESTARTER">https://github.com/tud-zih-energy/FIRESTARTER</a><br />
<strong>Requirements:</strong>  Python and a C compiler (I have not confirmed the OSX or Windows versions; the code is native to Linux)</p>

<p><strong>TL;DR:</strong> Programmers (and processor architects) usually write with some intent in mind, and the resulting work can be measured against how closely it matches that intent.  Once the code escapes into the wild, it can be endlessly repurposed, and the original intents of the authors gradually fade away.  In this critique I'll be focusing on two cases where the meaning of repurposed code depends entirely on its externalities:  the text of the code becomes divorced from its meaning; the execution of the code is only needed to trigger the external effects.  Calling the process "misreading code" doesn't quite capture the sense of mischief involved, but it's close.</p>

<p><strong>The Story of Mel</strong></p>

<p><a rel="nofollow" href="https://en.wikipedia.org/wiki/Eric_S._Raymond" title="https://en.wikipedia.org/wiki/Eric_S._Raymond">Eric S. Raymond</a> continues to maintain the collection of hacker lore known as the <a rel="nofollow" href="http://catb.org/jargon/html/" title="catb.org/jargon/html/">Jargon File</a>.  It's origins go back to 1975, and along with hundreds of definitions of programmer slang of that era it also contains a few longer pieces that distill that culture.  <a rel="nofollow" href="http://catb.org/jargon/html/story-of-mel.html" title="catb.org/jargon/html/story-of-mel.html">The Story of Mel</a> (Ed Nather, 1983) describes the oldest description of code misreading I know of--there are certainly older ones out there--and manages to do so in (unintentional) free verse.  It begins:</p>

<blockquote><div>
  <p>A recent article devoted to the macho side of programming<br />
  made the bald and unvarnished statement:<br />
  <br />
   Real Programmers write in FORTRAN.<br />
  <br />
  Maybe they do now,<br />
      in this decadent era of<br />
      Lite beer, hand calculators, and “user-friendly” software<br />
      but back in the Good Old Days,<br />
      when the term “software” sounded funny<br />
      and Real Computers were made out of drums and vacuum tubes,<br />
      Real Programmers wrote in machine code.<br />
      Not FORTRAN.  Not RATFOR.  Not, even, assembly language.<br />
      Machine Code.<br />
      Raw, unadorned, inscrutable hexadecimal numbers.<br />
      Directly.</p>
</div></blockquote>

<p>The text goes on to describe Mel, a Real Programmer:</p>

<blockquote><div>
  <p>Mel never wrote time-delay loops, either,<br />
      even when the balky Flexowriter<br />
      required a delay between output characters to work right.<br />
      He just located instructions on the drum<br />
      so each successive one was just past the read head<br />
      when it was needed;<br />
      the drum had to execute another complete revolution<br />
      to find the next instruction.<br />
      He coined an unforgettable term for this procedure.<br />
      Although “optimum” is an absolute term,<br />
      like “unique”, it became common verbal practice<br />
      to make it relative:<br />
      “not quite optimum” or “less optimum”<br />
      or “not very optimum”.<br />
      Mel called the maximum time-delay locations<br />
      the “most pessimum”.</p>
</div></blockquote>

<p>That's a fun hacker story, but it gains a bit more meaning from a CCS perspective.  The drum manufacturer didn't intend for their equipment to be used as an impromptu delay loop.  Looking at the text of Mel's code would have revealed instructions carefully splattered across the entire drum, but nothing in the documentation of those instructions would have revealed why that would have been useful.  It's only after the externalities are accounted for that the code (and its layout) is revealed as an instance of genius.  We're not quite to the point where the code is <em>only</em> triggering externalities; for that, we turn to FIRESTARTER.  But first, a quick note each about processor architecture and vector instructions.</p>

<p><strong>A very brief primer on power and processor architecture</strong></p>

<p>Here's what you need to know about the recent evolution of processor architecture.  Keeping bits on or off requires very little energy.  Switching back and forth takes substantially more energy and generates a lot more heat.  Increasing the clock frequency of the processor makes the problem worse, as does increasing the number of bits.  Vector instructions use lots of bits (up to 512 per register compared with the usual 32 or 64), and each additional core has its own set of vector registers.  Doing lots of vector arithmetic a the highest clock frequency will destroy the processor in a handful of milliseconds.  Intel processors (and a few others) monitor how much power is being used and how much heat is being generated.  As the processor's limit is reached, the firmware will slow down the processor.  As electrical and thermal headroom is restored, the firmware speeds the processor back up.  This dithering of clock speeds can happen dozens of times per second and is effectively nondeterministic.</p>

<p><strong>Meet a vector instruction</strong></p>

<p>Say hello to <code>vfmadd231pd</code>, a <strong>f</strong>used <strong>m</strong>ultiply-<strong>add</strong> <strong>v</strong>ector instruction that, according to  <a rel="nofollow" href="https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf" title="https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf">Volume 2</a> of Intel's software development manual, will allow the programmer to:</p>

<blockquote><div>
  <p>[m]ultiply packed double-precision floating-point values from [the register] xmm2 and xmm3/mem, add to xmm1 and put result in xmm1 (page 5-120)</p>
</div></blockquote>

<p>From a CCS perspective, we can now say something about a bit of actual code, say....</p>

<pre><code>vfmadd231pd %%zmm5, %%zmm0, %%zmm4
</code></pre>

<p>There's even a <a rel="nofollow" href="https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation#Fused_multiply%E2%80%93add" title="https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation#Fused_multiply%E2%80%93add">Wikipedia page</a> devoted to this class of instructions (of course there is), where we learn that fused-multiply-accumulate instructions are useful for speeding up matrix multiplication, neural networks, blah blah blah.  In isolation, that's about as far as we can go.  So let's look at a bit of context.</p>

<p><strong>FIRESTARTER</strong></p>

<p>Here's a sliver of the hand-crafted assembly that comprises FIRESTARTER, a processor stress test created by another Real Programmer, Daniel Hackenberg at TU-Dresden.  The original code is written in Python, which generates C with inline assembly code (as there's no way of convincing a compiler that any pure-C code should result in this).  If you're not familar with assembly, no worries---just unfocus your eyes and look for patterns.  The more familiar you are with assembly, the stranger this code appears:  it looks very much like busywork.  The following code begins at line 587 of avx512_functions.c.</p>

<pre><code>        &quot;.align 64;&quot;     /* alignment in bytes */
        &quot;_work_loop_skl_xeonep_avx512_1t:&quot;
        /****************************************************************************************************
         decode 0                                 decode 1                                 decode 2             decode 3 */
        &quot;vmovapd %%zmm3, 64(%%r9);                vfmadd231pd %%zmm4, %%zmm0, %%zmm3;      shl $1, %%edi;       add %%r14, %%r9;    &quot; // RAM store
        &quot;vfmadd231pd %%zmm5, %%zmm0, %%zmm4;      vfmadd231pd %%zmm6, %%zmm1, %%zmm26;     shl $1, %%esi;       xor %%rdi, %%r13;   &quot; // REG ops only
        &quot;vfmadd231pd %%zmm6, %%zmm0, %%zmm5;      vbroadcastsd 64(%%rbx), %%zmm5;          shl $1, %%edx;       add %%r14, %%rbx;   &quot; // L1 packed single load
        &quot;vfmadd231pd %%zmm7, %%zmm0, %%zmm6;      vfmadd231pd %%zmm8, %%zmm1, %%zmm27;     shr $1, %%edi;       xor %%rdx, %%r13;   &quot; // REG ops only
        &quot;vfmadd231pd %%zmm8, %%zmm0, %%zmm7;      vfmadd231pd 64(%%rbx), %%zmm1, %%zmm7;   shr $1, %%esi;       add %%r14, %%rbx;   &quot; // L1 load
        &quot;vfmadd231pd %%zmm9, %%zmm0, %%zmm8;      vbroadcastsd 64(%%rbx), %%zmm8;          shr $1, %%edx;       add %%r14, %%rbx;   &quot; // L1 packed single load
        &quot;vfmadd231pd %%zmm10, %%zmm0, %%zmm9;     vfmadd231pd %%zmm11, %%zmm1, %%zmm28;    shl $1, %%edi;       xor %%rdx, %%r13;   &quot; // REG ops only
        &quot;vfmadd231pd %%zmm11, %%zmm0, %%zmm10;    vfmadd231pd 64(%%rcx), %%zmm1, %%zmm10;  shl $1, %%esi;       add %%r14, %%rcx;   &quot; // L2 load
        &quot;vfmadd231pd %%zmm12, %%zmm0, %%zmm11;    vfmadd231pd %%zmm13, %%zmm1, %%zmm29;    shl $1, %%edx;       xor %%rsi, %%r13;   &quot; // REG ops only
        &quot;vfmadd231pd %%zmm13, %%zmm0, %%zmm12;    vbroadcastsd 64(%%rbx), %%zmm12;         shr $1, %%edi; 
</code></pre>

<p>If you're a processor architect, what jumps out is how busy this processor is.  All four instruction decoders are in use, none of the instructions are conflicting with each other (meaning there are no stalls why the processor waits for results to complete or arrive), and.... it's all nonsense.</p>

<p>We're used to thinking of code in terms of symbolic language:  each variable and function is a symbol (representation, model, approximation, whatever term you like to use) of some other thing or action.  <strong>In the code above, FIRESTARTER has removed the symbolic meaning from code.</strong>  The instructions are being used exclusively to turn actual bits on and off as fast as possible, thus maximizing power and thermal load.  The actual mathematical results are overwritten and recalculated again and again---they don't have any meaning as math, they are just a vehicle for flipping bits.</p>

<p>(In terms of speech acts, FIRESTARTER performs a stream of phonetic and phatic acts (noises and words, respectively) which result in a perlocutionary act (the processor heats up) without reaching an illucutionary act (saying something understandable).  I'm far from an expert, though, so I'd be happy to hear other opinions.)</p>

<p><strong>Misreading code</strong></p>

<p>What Hackenberg has accomplished is a deliberate, careful misreading of code (more specifically, the instruction set architecture).  The intent of the processor architects at Intel was to create specialized instructions for matrix-related mathematics, but the fact that this intent exists does not preclude additional readings.  By taking into account the environment in which the intent was realized, Hackeberg can misread these instructions in order to control secondary effects like power consumption and heat generation.</p>

<p>This kind of misreading is most common in security programming (<a rel="nofollow" href="https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)" title="https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)">Spectre</a>/<a rel="nofollow" href="https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)" title="https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)">Meltdown</a>, <a rel="nofollow" href="https://en.wikipedia.org/wiki/Row_hammer" title="https://en.wikipedia.org/wiki/Row_hammer">Rowhammer</a>, <a rel="nofollow" href="https://plundervolt.com/" title="https://plundervolt.com/">Plundervolt</a>).  In each case, the externalities of the running code allow for privilege escalation.</p>

<p><strong>Misreading FIRESTARTER</strong></p>

<p>So far I've described FIRESTARTER as a program that maximizes the power and thermal response of a processor.  That was certainly the intent of the authors.  Part of the information it reports is how many iterations of its main loop have executed.  These are relatively small loops, so the count tends to be quite large.  Here is an example of the output from running on my i9-9900K workstation at home.  (Note that FIRESTARTER isn't optimized for this processor.)</p>

<p>My machine starts off at 28C with the water pump fans off.  Within a couple second after starting the program, the processor temperature has peaked at 99C and the pump fans are spinning up.  (The clock frequency will be dropping here.)  One those fans are up to speed the processor stays at a reasonable 65C until the run completes.  Here's a portion of what FIRESTARTER reports.</p>

<pre><code>performance report:

Thread 0: 118513178 iterations, tsc_delta: 216052936842
Thread 1: 117377514 iterations, tsc_delta: 215995301932
Thread 2: 118972471 iterations, tsc_delta: 215995301370
Thread 3: 116601636 iterations, tsc_delta: 215995301040
Thread 4: 117583482 iterations, tsc_delta: 215995300430
Thread 5: 118341824 iterations, tsc_delta: 215995300118
Thread 6: 116436094 iterations, tsc_delta: 215995298734
Thread 7: 116491650 iterations, tsc_delta: 215995298446
Thread 8: 120026957 iterations, tsc_delta: 215995299742
Thread 9: 119539717 iterations, tsc_delta: 215995297710
Thread 10: 118192628 iterations, tsc_delta: 215995296440
Thread 11: 116883387 iterations, tsc_delta: 215995296062
Thread 12: 117503542 iterations, tsc_delta: 215995294898
Thread 13: 117667925 iterations, tsc_delta: 215995294150
Thread 14: 119323114 iterations, tsc_delta: 215995293560
Thread 15: 116124503 iterations, tsc_delta: 215995291304

total iterations: 1885579622
runtime: 60.02 seconds (216052936842 cycles)

estimated floating point performance: 233.73 GFLOPS
estimated memory bandwidth*: 20.11 GB/s

* this estimate is highly unreliable if --function is used in order to select
  a function that is not optimized for your architecture, or if FIRESTARTER is
  executed on an unsupported architecture!
</code></pre>

<p>Note that the Time Stamp Counter difference (aka tsc_delta) is accurate well within 0.1%; Linux knows how to start and stop execution in the time requested (here, 60 seconds).</p>

<p>But also note that the number of iterations varies quite a bit more than that from thread to thread, from a max of 120026957 to a min of 116124503 iterations completed.</p>

<p>What happens if I run FIRESTARTER 350 times?  There is a fair amount of run-to-run variation, but it occurs within a band.</p>

<p>What happens if I run FIRESTARTER 350 on 4,200 ostensibly identical processors (the Quartz supercomputer at LLNL)?</p>

<p>Recall that I mentioned the clock frequency (and thus the number of iterations) depends on the thermal and power load, and that makes deterministic performance more or less impossible.  It turns out that the major source of that variation is the variation within the silicon of individual processors.  More efficient processors use less power to push bits down their wires, so they can run faster without getting as hot.  Less-efficient processors heat up more when running slowly and often can't reach theoretical maximum frequencies at all.</p>

<p>What does that look like?  Rather than show you all 4,200 processors, here's the best, worst and median one out of the bunch.</p>

<p><img src="http://wg20.criticalcodestudies.com/uploads/editor/it/kopp03xlk9vs.png" alt="" title="" /></p>

<p>Each box-and-whisker plot shows run-to-run variation (thanks, Linux).  There are two hyperthreads per core; there is both core-to-core and hyperthread-to-hyperthread variation (hyperthread 0 is consistently a bit worse than hyperthread 1, and core 12 is consistently better than core 13).</p>

<p>But the processor-to-processor variation dominates.  There are the same model and stepping, yet there's an easy 10% difference between the median of the best and the median of the worst processor.  (This is known as the "silicon lottery.")</p>

<p>Ok, so what?</p>

<p>Using a bit of undergrad statistics (not shown here), you could run FIRESTARTER for a minute on a random processor and, despite all the variation going on, I'd be able to identify which processor you chose.</p>

<p><em>In short, I have misread FIRESTARTER to get to the externalities that provide a unique signature for each of 4,200  processors.</em>  The FIRESTARTER authors didn't anticipate this.  By misreading what they've done, I've gained access to physical information we didn't have before.  And <em>that</em> leads to some really gnarly security issues that I'll leave for another time.</p>

<p><strong>Why this matters to CCS</strong></p>

<p>When I was a wee Theater undergrad I had it drilled into my head how the performance consisted of not only actors performing, but the audience and their expectations, the architecture of the theater, subtleties of lighting, sound, costume, gesture, facial expression.... and we have vocabulary and frameworks to discuss how those choices will affect what the audiences takes home.  We don't ask whether we can or should misread Shakespeare---that's done as a matter of course.  We can do things like stage the first act of Strinberg's <em>Dream Play</em> in the parking lot of an abandoned funeral home in the middle of San Diego where the actors are all mute and their lines have been pre-recorded and are played over loudspeakers (thank you, Sledgehammer Theater).  The kind of curiosity and creativity required for that staging feels similar to what's needed for Mel spattering instructions all over his drum memory or Daniel Hackenberg jacking up processor power by executing nonsense fused-multiply-add instructions.  We know how to teach those skills to theater students.  We're nowhere close to doing that for CS students.</p>

<p>As a computer scientist, I don't have either the vocabulary or frameworks to explain how I go about my misreadings (and I've built my career on them).  I would like to give my students and interns an apparatus (or several) that allows them to think about code like their colleagues in the theater department think about performance.  I suppose you could say that I want them to read code critically.  I'm hoping that CCS can eventually provide that scaffolding.</p>

<p><strong>Questions for Discussion</strong></p>

<ol>
<li>You made it this far?  You badass!</li>
<li>Where in the above did your eyes begin to glaze over?</li>
<li>What are your experiences with deliberate misreading of code?</li>
<li>How do you teach your students how to be creative, and how would you apply that to teaching CS students?</li>
</ol>
]]>
        </description>
    </item>
    <item>
        <title>"Coding Issue" in 2020 Election app</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/91/coding-issue-in-2020-election-app</link>
        <pubDate>Tue, 04 Feb 2020 15:55:32 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">91@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>In a stellar moment in early 21st Century app-ocratic elections, the Democratic party's newly rolled out  caucus results reporting app failed in epic fashion.  In the place of the usual suspects, foreign hackers, a number of news outlets have placed the blame on the programmer, or specifically the coders.  Not to say, "fake news," but consider these headlines:</p>

<p><a rel="nofollow" href="https://www.msn.com/en-us/news/politics/in-embarrassing-twist-democrats-have-no-iowa-caucus-results/ar-BBZD8LJ" title="Democrats have no Iowa caucus results, blame 'coding issue'">Democrats have no Iowa caucus results, blame 'coding issue'</a><br />
<a rel="nofollow" href="https://www.staradvertiser.com/2020/02/03/breaking-news/biden-claims-success-in-iowa-despite-vote-delay/" title="Democrats have no Iowa caucus results, blame ‘coding issue’">Democrats have no Iowa caucus results, blame ‘coding issue’</a><br />
<a rel="nofollow" href="https://www.theverge.com/2020/2/4/21122252/iowa-democrats-caucus-results-coding-issue-app-data-transmission" title="Iowa Democrats blame ‘coding issue’ for botched caucus results">Iowa Democrats blame ‘coding issue’ for botched caucus results</a></p>

<p>The headline comes from a statement from Iowa Democratic Party Chair Troy Price:</p>

<blockquote><div>
  <p>“While the app was recording data accurately, it was reporting out only partial data,” Price said. “We have determined that this was due to a coding issue in the reporting system.”</p>
</div></blockquote>

<p>With the caucus "meltdown," coding is once again the center of social conflict. As elections more and more rely on electronic means, black-boxed code (black boxed for security reasons) takes the place of the ballot boxes with their the hanging chads.  But the ideal of democracy hinges on notions of transparency, accountability, and the mythical "free and fair elections."  Code becomes a surrogate or proxy for the unseen machinations or in this case, the failures of political machinery.</p>

<p>Coding, in this case takes some of the pressure off of humans. Take this line:</p>

<blockquote><div>
  <p>Des Moines County Democratic Chair Tom Courtney said the new app created “a mess.”</p>
</div></blockquote>

<p>Election software epitomizes that critical code that affects so many vital facets of our lives. Both <a rel="nofollow" href="http://wg20.criticalcodestudies.com/index.php?p=/profile/DavidBerry">@DavidBerry</a> and I have written about open source voting software.  But again, the code for this software is not in the public eye, presumably to avoid hacking. As NPR reporter Miles Parks commented before the election:</p>

<blockquote><div>
  <p>It's one thing to introduce a new piece of election technology without really any practice beforehand, and then it's another thing to introduce that piece of election technology without giving any security details about it. We know very little about the specifics of this app. We don't know who developed it or who wrote the code. We don't know what sorts of security tests have been performed on it. These are the two basic questions that any security expert would ask when confronting a new system. And the Democratic Party says, basically, they're not going to provide any of this information because they're scared it would help hackers. But experts actually say that that secrecy doesn't help against hacking at all.</p>
</div></blockquote>

<p>I look forward when the Freedom of Information Act makes the code for the Iowa App available for investigation, <a rel="nofollow" href="https://www.justice.gov/oip/blog/foia-update-department-justice-report-electronic-record-foia-issues-part-ii" title="assuming that applies">assuming that applies</a>.</p>

<p>Meanwhile, in Iowa, they are reportedly back to tallying votes on paper.</p>

<p>What role does "coding" play in our discussion of this debacle?  How does this news story speak to public perceptions of coding?</p>
]]>
        </description>
    </item>
    <item>
        <title>Abstraction, disembodiment, and the environmental impacts of technology</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/93/abstraction-disembodiment-and-the-environmental-impacts-of-technology</link>
        <pubDate>Wed, 05 Feb 2020 06:10:58 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>liliang</dc:creator>
        <guid isPermaLink="false">93@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Title:</strong> Neural network example in Keras<br />
<strong>Author/s:</strong> Keras docs (not sure exactly who wrote it)<br />
<strong>Language/s:</strong> Python<br />
<strong>Year/s of development:</strong> 2019<br />
<strong>Software/hardware requirements (if applicable):</strong> Anything ranging from just your computer to 64 GPUs</p>

<h1>Abstraction, disembodiment, and the environment</h1>

<p>Below is a snippet of code showing how to set up a small single-input neural network that performs binary classification in Keras (a popular deep learning framework in Python):</p>

<pre><code># For a single-input model with 2 classes (binary classification):
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# Generate dummy data
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)
</code></pre>

<p>This example code comes from <a rel="nofollow" href="https://keras.io/getting-started/sequential-model-guide/" title="a guide">a guide</a> found in the Keras docs. The chunk of code under the first comment creates a sequential model with two Dense layers and compiles it. The chunk of code under the second comment generates dummy training data and labels. Finally, the last line of code trains the model by passing in training data and labels into a function called “fit”.</p>

<p>I want to focus specifically on the seemingly simple “fit” function. Many other machine learning frameworks are similar in that after setting up the model architecture and training data, all you have to do is call the “fit” method to actually train the model and the framework will take care of the rest.</p>

<p>On one hand, this abstraction is really helpful. You don’t need to backpropagate millions of weights by hand. You don’t even need to know what backpropagation means. As long as you define a model architecture and feed in some training data and labels, you can train a model. This lowers the barrier of entry to training a neural network.</p>

<p>But on the other hand, we pay an environmental price for this abstraction that we don’t immediately internalize. The sample I posted here is a toy example. But imagine if we had a much larger network like <a rel="nofollow" href="https://arxiv.org/pdf/1810.04805.pdf" title="BERT">BERT</a>, which is a state-of-the-art neural network developed by Google and used for a variety of NLP (natural language processing) tasks. The smaller model (BERT base) has 110 million total parameters and the larger model (BERT large) has 340 million. <a rel="nofollow" href="https://arxiv.org/pdf/1906.02243.pdf" title="A paper">A paper </a>published last year by the University of Massachusetts Amherst detailing the energy usage of deep learning in NLP shows that “[...] training BERT on GPU is roughly equivalent to a trans-American flight” (see Table 3 on page 4 of the paper). The amount of computational resources needed to train BERT is enormous: “NVIDIA reports that they can train a BERT model in 3.3 days (79.2 hours) using 4 DGX-2H servers, totaling 64 Tesla V100 GPUs”.</p>

<p>There are even more abstractions that make training models easier but also further distances us from its actual physical impacts. Don’t own 64 GPUs? No problem. You can pay AWS (Amazon Web Services) or Google Cloud to use their computing resources. It is common practice now to train models “in the cloud”. Now there really is no immediate physical indicator of how much computing resources you’re using. It’s all just ~ in the cloud ~</p>

<p>Abstraction is a holy tenet of software engineering. In my computer science classes, I was taught to hide all unnecessary complexities behind clearly defined, easy-to-use APIs. I never considered that a side effect of all this abstraction was a sense of disembodiment. The idea that there are physical limitations is as obvious as saying “water is wet” and yet, something I rarely think about as a software engineer. I just always assume that I will have the computing resources I need.</p>

<h1>Reembody and Reimagine</h1>

<p>Grappling with the disembodiment of abstraction and virtual space reminds me of a beautiful essay published by the MIT Press called “<a rel="nofollow" href="https://jods.mitpress.mit.edu/pub/lewis-arista-pechawis-kite" title="Making Kin with the Machines">Making Kin with the Machines</a>” (Disclaimer: this was published as a critique/response to a manifesto Joi Ito wrote while he was still at MIT. However, he is not an author of the essay). This paragraph sums up what I hope to learn and discuss through the lens of Indigenous programming:</p>

<blockquote><div>
  <p>“One of the challenges for Indigenous epistemology in the age of the virtual is to understand how the archipelago of websites, social media platforms, shared virtual environments, corporate data stores, multiplayer video games, smart devices, and intelligent machines that compose cyberspace is situated within, throughout and/or alongside the terrestrial spaces Indigenous peoples claim as their territory. <strong>In other words, how do we as Indigenous people reconcile the fully embodied experience of being on the land with the generally disembodied experience of virtual spaces?</strong> How do we come to understand this new territory, knit it into our existing understanding of our lives lived in real space, and claim it as our own?”</p>
</div></blockquote>

<p>As someone who is currently living on stolen Duwamish lands, I am not the right person to answer these questions. So I would really love to learn from people who are or anyone could better expand upon these topics:<br />
1. [From the paragraph above]: How do we as Indigenous people reconcile the fully embodied experience of being on the land with the generally disembodied experience of virtual spaces? How do we come to understand this new territory, knit it into our existing understanding of our lives lived in real space, and claim it as our own?<br />
2. We are currently in a climate crisis that is only going to get worse. Not only is there an environmental impact from machine learning, but also huge impacts from data storage, networks, and the mining of minerals for devices to name a few. In the essay, the authors (who are Indigenous peoples themselves) state: “We undertake this project not to “diversify” the conversation. We do it because we believe that Indigenous epistemologies are much better at respectfully accommodating the non-human.” And I wholly agree. What are different Indigenous lenses we can look through to incorporate technology respectfully with the environment? What about other lenses?</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: "Who Are You In 1917 Russia?" and arbitrariness in political compass tests</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/74/code-critique-who-are-you-in-1917-russia-and-arbitrariness-in-political-compass-tests</link>
        <pubDate>Thu, 30 Jan 2020 16:21:56 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>JoeyJones</dc:creator>
        <guid isPermaLink="false">74@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Political Compass of the Revolution<br />
Authors: Alexander Reznik,Dmitry Golubovsky,Paul Richardson<br />
Language: HTML, CSS, Javascript<br />
Software requirement: Any modern browser<br />
Link to quiz: <a rel="nofollow" href="https://arzamas.academy/materials/1269">https://arzamas.academy/materials/1269</a></p>

<p>First launched in 2001, the <a rel="nofollow" href="https://www.politicalcompass.org/" title="Political Compass">Political Compass</a> quiz has made an indelible mark on online political discussion, popularising a two-axis political spectrum and launching thousands of memes. In the quiz, the participant answers strongly agree, agree, disagree, strongly disagree on a number of questions, each answer having a hidden point rank which moves them up and down two scales of authoritarian/libertarian and left/right. The outcome is a point on a four-quadrant chart.</p>

<p>The trouble with this format is that even if it were possible to word and present the questions in a non-leading way (something the original political compass actively avoids doing), the point values would still necessarily be arbitrary. This can be seen in the code below. As the Political Compass's source is hidden, I have presented one of it's successor quizes instead. This Political Compass of the Revolution has the same structure as its forebear. However rather than trying (and failing) to reflect an ideology for all people, places and times, it focuses purely on specific factions in a specific time and place (namely, the main political groupings in Russia in 1917). In this way it is more informative than the original Political Compass (the specific positions on the chart actually reflect real positions), and it is able to tell you which faction your answers are closest to, and what those factions answers would be.</p>

<p>Here's a relevant section of the code, which shows the questions and the point values for their answers:</p>

<pre><code> questions: [
      {
        id: 1,
        title: 'Private property is&amp;nbsp;a&amp;nbsp;natural right and a&amp;nbsp;vital economic institution.',
        answersWeight: [16, 8, 0, -8, -16],
        axis: 'x'
      },
      {
        id: 2,
        title: 'The agrarian question can only be&amp;nbsp;resolved through socialization of&amp;nbsp;all land. Land should become the property of&amp;nbsp;the people as&amp;nbsp;a&amp;nbsp;whole and should not be&amp;nbsp;bought and sold!',
        answersWeight: [-32, -16, 0, 16, 32],
        axis: 'x'
      },
      {
        id: 3,
        title: 'I&amp;nbsp;favor swift nationalization of&amp;nbsp;the key sectors of&amp;nbsp;industry.',
        answersWeight: [-14, -7, 0, 7, 14],
        axis: 'x'
      },
      {
        id: 4,
        title: 'A&amp;nbsp;universal shortening of&amp;nbsp;the workday to&amp;nbsp;eight hours is&amp;nbsp;essential.',
        answersWeight: [-14, -7, 0, 7, 14],
        axis: 'x'
      },
      {
        id: 5,
        title: 'The workers must be&amp;nbsp;given control of&amp;nbsp;industrial enterprises.',
        answersWeight: [-14, -7, 0, 7, 14],
        axis: 'x'
      },
      {
        id: 6,
        title: 'Elections should be&amp;nbsp;universal, direct, fair and secret.',
        answersWeight: [6, 3, 0, -3, -6],
        axis: 'y'
      },
      {
        id: 7,
        title: 'The State, as&amp;nbsp;a&amp;nbsp;matter of&amp;nbsp;principle, does not have a&amp;nbsp;right to&amp;nbsp;limit freedom of&amp;nbsp;speech or&amp;nbsp;assembly!',
        answersWeight: [8, 4, 0, -4, -8],
        axis: 'y'
      },
      {
        id: 8,
        title: 'Women should receive rights equal to&amp;nbsp;those of&amp;nbsp;men!',
        answersWeight: [6, 3, 0, -3, -6],
        axis: 'y'
      },
      {
        id: 9,
        title: 'The Church should be&amp;nbsp;separated from the State!',
        answersWeight: [6, 3, 0, -3, -6],
        axis: 'y'
      },
      {
        id: 10,
        title: 'The death penalty is&amp;nbsp;a&amp;nbsp;vital means of&amp;nbsp;punishment during current wartime conditions.',
        answersWeight: [-6, -3, 0, 3, 6],
        axis: 'y'
      },
      {
        id: 11,
        title: 'The war with Germany, Austro-Hungary, Bulgaria and the Ottoman Empire has been going on&amp;nbsp;for three years. This war must be&amp;nbsp;swiftly ended through a&amp;nbsp;democratic peace without annexations or&amp;nbsp;levies!',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 12,
        title: 'It&amp;nbsp;is&amp;nbsp;vital to&amp;nbsp;defend the Revolution, but not to&amp;nbsp;carry out attacks!',
        answersWeight: [-2, -1, 0, 1, 2],
        axis: 'y'
      },
      {
        id: 13,
        title: 'We&amp;nbsp;should honor our responsibilities to&amp;nbsp;our allies. War until a&amp;nbsp;victorious end!',
        answersWeight: [-4, -2, 0, 2, 4],
        axis: 'y'
      },
      {
        id: 14,
        title: 'Democratization of&amp;nbsp;the&amp;nbsp;army is&amp;nbsp;good. There is no&amp;nbsp;need for&amp;nbsp;military insignia, officers should be&amp;nbsp;elected, they must be&amp;nbsp;equal in&amp;nbsp;rights with soldiers.',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 15,
        title: 'Military dictatorship is&amp;nbsp;the best way to&amp;nbsp;get out of&amp;nbsp;the revolutionary crisis.',
        answersWeight: [-6, -3, 0, 3, 6],
        axis: 'y'
      },
      {
        id: 16,
        title: 'I&amp;nbsp;support the Provisional Government!',
        answersWeight: [-4, -2, 0, 2, 4],
        axis: 'y'
      },
      {
        id: 17,
        title: 'The present state of&amp;nbsp;the Revolution demands a&amp;nbsp;lengthy period of&amp;nbsp;agreement between all democratic forces.',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 18,
        title: 'I&amp;nbsp;am for the swift convocation of&amp;nbsp;the Constituent Assembly!',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 19,
        title: 'The Soviets of&amp;nbsp;Worker, Soldier and Peasant Deputies should take over the reigns of&amp;nbsp;state power!',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 20,
        title: 'The city Dumas (legislatures) are the proper mechanism for self-government, we&amp;nbsp;don&amp;rsquo;t need any other.',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 21,
        title: 'The working class is&amp;nbsp;the driving force of&amp;nbsp;the Revolution.',
        answersWeight: [-14, -7, 0, 7, 14],
        axis: 'x'
      },
      {
        id: 22,
        title: 'The State should be&amp;nbsp;swiftly liquidated and replaced by&amp;nbsp;the people&amp;rsquo;s self-government.',
        answersWeight: [24, 12, 0, -12, -24],
        axis: 'y'
      },
      {
        id: 23,
        title: 'A&amp;nbsp;federal state structure is&amp;nbsp;the best option for multinational Russia.',
        answersWeight: [8, 4, 0, -4, -8],
        axis: 'y'
      },
      {
        id: 24,
        title: 'Russia should continue to&amp;nbsp;be&amp;nbsp;a&amp;nbsp;major power, retaining its continental and overseas colonies, ruled from the center.',
        answersWeight: [-6, -3, 0, 3, 6],
        axis: 'y'
      },
      {
        id: 25,
        title: 'A&amp;nbsp;multiparty system is&amp;nbsp;capable of&amp;nbsp;serving to&amp;nbsp;stabilize democratic power.',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 26,
        title: 'Russia&amp;rsquo;s political system should develop in&amp;nbsp;the direction of&amp;nbsp;parliamentarianism.',
        answersWeight: [4, 2, 0, -2, -4],
        axis: 'y'
      },
      {
        id: 27,
        title: 'Our end goal is&amp;nbsp;socialism!',
        answersWeight: [-14, -7, 0, 7, 14],
        axis: 'x'
      },
    ],
</code></pre>

<p>There's presumably some rationale why strongly agreeing to question 23 should move you 8 points along the Y axis while strongly agreeing to 25 moves you half as much. Even if we allow that there is an art to judging the comparative ideological significance of any given opinion, the exact numbers chosen cannot escape being somewhat arbitrary.</p>

<p>Note that the purpose of the quiz is achieved without reference to the axis position: at the end of the quiz it judges how close your answers are to the answers of other historical actors, and that can be done just by comparing your answer with theirs: the exact point values of these answers don't matter. In this way, this version of the political compass points the way towards more meaningful ideology tests.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Ruben and Lullaby by Erik Loyer</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/68/code-critique-ruben-and-lullaby-by-erik-loyer</link>
        <pubDate>Mon, 27 Jan 2020 03:34:30 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">68@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Rube &amp; Lullaby<br />
Author: Erik Loyer<br />
Link: <a href="https://github.com/eloyer/ruben-and-lullaby" rel="nofollow">https://github.com/eloyer/ruben-and-lullaby</a><br />
Year: 2009</p>

<p>Upon the occasion of CCSWG20, artist Erik Loyer has shared the code for Ruben &amp; Lullaby, a wonderful iOS work in which you play (as in playing a musical instrument) a conversation between two fighting lovers.  You can make it worse by aggravating them or try to smooth things out, as you interact to calm them down (via rubbing the screen) or irritate them (by shaking it).  The piece also features a "dynamic score," which is also affected by user interaction.</p>

<p>Erik has pointed us in some potential areas of interest:<br />
Input is handled in EAGLView.m — both accelerometer (tilt to cut, shake to anger) and touch (tap to change eye position, stroke to calm).</p>

<blockquote><div>
  <p>The logic behind the story mechanics, shot transitions, and the dynamic score is all contained in StoryManager.m — I'm interested in exploring these as potential constraints on live performance by actors and musicians.</p>
  
  <p>The XML file rl_data.xml contains data describing each character view, as well as a script that serves as a kind of superstructure for the experience.</p>
  
  <p>In Localizable.strings you can find the vestiges of an abandoned attempt to make the story mechanics easier to grasp through text.</p>
</div></blockquote>

<p>Here's a demo of the app.<br />
<span data-youtube="youtube-TgFlkbCbCg8?autoplay=1"><a rel="nofollow" href="https://www.youtube.com/watch?v=TgFlkbCbCg8"><img src="https://img.youtube.com/vi/TgFlkbCbCg8/0.jpg" width="640" height="385" border="0" alt="image" /></a></span></p>

<p>Let's explore.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique:  What Python does when it's doing nothing.</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/60/code-critique-what-python-does-when-its-doing-nothing</link>
        <pubDate>Mon, 20 Jan 2020 21:56:38 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>barry.rountree</dc:creator>
        <guid isPermaLink="false">60@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Code Critique</strong>:  nothing.py</p>

<p><strong>Language:</strong> Python</p>

<p><strong>Authors:</strong> n/a</p>

<p><strong>Years:</strong> 1990-</p>

<p><strong>Works cited:</strong> Frings et al., <a rel="nofollow" href="https://dl.acm.org/doi/10.1145/2464996.2465020">Massively Parallel Loading</a>, ICS 2013. (<a rel="nofollow" href="https://computing.llnl.gov/projects/spindle/spindle-paper.pdf">pdf</a>)</p>

<p><strong>TL;DR</strong> Extracting meaning from code requires understanding (modeling) what is left unsaid.</p>

<hr />

<p>The code I'll be critiquing is an empty python script, perhaps the computer science equivalent of <a rel="nofollow" href="https://en.wikipedia.org/wiki/4%E2%80%B233%E2%80%B3">4'33''</a>.</p>

<p>Creating the code is trivial on any *nix machine:<br />
    $ python --version<br />
    Python 2.7.17<br />
    $ touch nothing.py<br />
    $ ls -l<br />
    total 0<br />
    -rw-r--r-- 1 rountree rountree 0 Jan 18 14:06 nothing.py<br />
    $</p>

<p><code>touch</code> creates and empty file with the specified filename, and <code>ls -l</code> shows the size of the file is indeed 0.  Running this code is about as exciting as you might expect.</p>

<pre><code>$ python ./nothing.py
$
</code></pre>

<p>The temptation is to think that nothing happened:  we didn't ask Python to do anything, and it complied with alacrity.  In most computing environments, that summary is a perfectly serviceable abstraction of what happened.  But it is an abstraction, and interesting things happen when ground truth starts diverging too far from our abstraction of it.</p>

<p>Let's take a closer look.</p>

<pre><code>$ strace python ./nothing.py 
execve(&quot;/usr/bin/python&quot;, [&quot;python&quot;, &quot;./nothing.py&quot;], 0x7ffc76d71d08 /* 56 vars */) = 0
brk(NULL)                               = 0x55a94fcaf000
access(&quot;/etc/ld.so.nohwcap&quot;, F_OK)      = -1 ENOENT (No such file or directory)
access(&quot;/etc/ld.so.preload&quot;, R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, &quot;/etc/ld.so.cache&quot;, O_RDONLY|O_CLOEXEC) = 3
....
</code></pre>

<p><code>strace</code> captures all of the calls that the Python interpreter makes into the linux kernel (<em>e.g.,</em> <code>brk</code>), lists the parameters for each of those calls (<code>NULL</code>) and the value that's returned (<code>0x55a94fcaf000</code>), possibly with an explanation if there's an error (<code>-1 ENOENT (No such file or directory)</code>).  What each of those individual lines mean to a systems programmer is beyond the scope of this critique.  The aggregate numbers are more interesting.</p>

<pre><code>$ strace python ./nothing.py 2&gt;&amp;1 | wc -l
746
</code></pre>

<p>The <code>2&gt;&amp;1</code> is a bit of magic to put output routed to <code>stderr</code> (which <code>strace</code> uses) to <code>stdout</code> (which the rest of the tools expect).  The pipe <code>|</code> routes the <code>stdout</code> of the prior command to the <code>stdin</code> of the next command. <code>wc -l</code> simply counts how many lines there are in <code>stdin</code> and outputs that number.</p>

<p>Roughly speaking, in order to run <code>nothing.py</code>, our Python interpreter made 746-ish calls into the linux kernel.</p>

<p>Which seems a little excessive.</p>

<p>Through the magic of bash one-liners we can get a sense of what's going on.</p>

<pre><code>$ strace python ./nothing.py 2&gt;&amp;1 | cut -d &quot;(&quot; -f 1 | sort | uniq -c | sort -rn | head
234 openat
 99 fstat
 98 read
 87 stat
 68 rt_sigaction
 66 close
 25 mmap
 14 mprotect
  8 brk
  8 access
 [only the top 10 shown]
</code></pre>

<p>That's 234 distinct attempts to open files.  On a laptop, that happens so fast as to be unnoticeable.  On a supercomputer, however....</p>

<blockquote><div>
  <p>KULL [15] is a large multi-physics application developed at LLNL. When it was first run on Dawn, an IBM BlueGene/P system, its start-up exposed serious scaling challenges and significantly disrupted the entire computing center. The KULL executable was dynamically linked to about one thousand shared libraries, most of them staged in an NFS file system to ease maintenance. Loading these libraries during program start-up scaled <em>extremely</em> poorly. The time from job launch to the initial invocation of KULL’s <code>main</code> function, for instance, took about one hour at 2,048 MPI processes and <em>ten</em> hours at 16,384 processes. Further, during start-up, the NFS server was overwhelmed with load requests from KULL, and other users and jobs were unable to connect to the NFS while KULL start-up continued. [Frings 2013, emphasis in original]</p>
</div></blockquote>

<p>The problem was that both the python libraries and those used by KULL itself were all located on single filesystem that the compute nodes accessed over the network.  16,384 processes starting up and simultaneously demanding 1,000+ libraries each utterly overwhelmed the filesystem.  The fix was clever enough to be published (distribute libraries via a tree network, see the paper for details), but doesn't inform this critique.</p>

<p>And with that background in place we can now do a code critique.</p>

<hr />

<p><em>So what does this code --- or lack of code --- actually mean?</em></p>

<p>Trawling through the Python source code to understand its initialization process would be tedious and error-prone.  It's much faster to run Python under instrumentation (in this case, <code>strace</code>) and watch what it does.  The empty script guaranteed that all the activity we'd be seeing would be coming from Python, not our code.</p>

<p><em>Ok, that's what you did, but you still haven't told me what it means.</em></p>

<p>Three points.</p>

<p>First, the text of code is an unreliable guide to its performance.  There may be a strong guarantee as to <em>correct</em> behavior, but there are rarely any guarantees about how that behavior will be accomplished.  The behavior of code is generally more important than its text, but that behavior is contingent upon everything from the rest of the computing ecosystem to the society in which the code operates.</p>

<p>Second, there might be a temptation to claim that if we had enough information about the system we could have perfect knowledge of the code's behavior.  We're never going to be able to get that much information out of nontrivial systems, so we're left with using simplified models.  As Box remarked:  "All models are wrong, but some are useful."  Becoming skilled in the art of system design, programming or code critiquing requires figuring out where your model can simplify without doing too much violence to your results.</p>

<p>Third, CCS understandably puts a great deal of emphasis on text.  This example is a corner case of how that approach can break down.  Unfortunately, learning how to do code instrumentation is at least as difficult as learning how to code in the first place, and there's definitely a lack of friendly guides to performance analysis.  One way around the problem might be more collaboration.</p>

<hr />

<p>Questions for discussion:</p>

<p>A. What examples of implied, misleading or ironic code have you come across in your own work?</p>

<p>B. What tools do you use to compare code-as-text versus code-as-performance?</p>

<p>C. How should CCS handle implied, misleading or ironic code?</p>

<hr />

<p>Notes:  I generated the example using Python 2.7.17 running on a Linux 5.0.0-37 kernel provided by Ubuntu 18.04.3 (Bionic Beaver).  Running Python 3.6.9 on that same machine only generates 67 calls to <code>openat</code>.</p>

<p>OSX users can substitute <code>dtruss</code> for <code>strace</code>, but doing so requires running as root and disabling system integrity protection.</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critique: Possibility and Injustice/Bias in AI Transfer Learning</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/72/code-critique-possibility-and-injustice-bias-in-ai-transfer-learning</link>
        <pubDate>Wed, 29 Jan 2020 02:57:01 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>gregorybringman</dc:creator>
        <guid isPermaLink="false">72@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><strong>Author/s</strong>: TensorFlow<br />
<strong>Language/s</strong>: Python, NumPy, TensorFlow, Keras, TensorFlow Hub<br />
<strong>Year/s of development</strong>: Current Learning Materials at tensorflow.org<br />
<strong>Location of code</strong>: <a href="https://www.tensorflow.org/tutorials/images/transfer_learning_with_hub" rel="nofollow">https://www.tensorflow.org/tutorials/images/transfer_learning_with_hub</a></p>

<p><strong>Overview</strong>:</p>

<p>In machine learning with neural networks, the practice of transfer learning uses one network trained for one task on another related but different task, without fully retraining the original network. This approach works in practice and it seems to mirror how humans use previous experience to learn new tasks. The learning of the new task in ML could then be thought of as “emergent” behavior, as the network classifies new input data under new categories.</p>

<p>There are lots of possibilities for philosophical reflection on this emergent behavior, although, transfer learning can also more clearly demonstrate how machine learning can be biased in potentially dangerous or unjust ways. In fact, in some of the early papers on multi-task and transfer learning, learning outcomes improve when ML learns with “bias”, a fact wholly accepted by the authors (see for example, R. Caruana, “Multitask Learning”. <em>Machine Learning</em>, vol. 28, 1997, p. 44).</p>

<p>That some bias is necessary in learning or knowledge production is an insight that philosophers have also come to understand through science studies and much contemporary thought. But this does not remove the potential danger or injustice. Consider an example of a transfer learning of possibility in multilingual language learning. Similarly, consider a transfer learning of injustice in facial recognition. These are possibilities and injustices that are present in neural networks in general. The code I would like to consider more fully dramatizes this bias however.</p>

<p>The code to consider comes from an ML tutorial on the TensorFlow.org website. TensorFlow is a higher level programming framework for neural network-based ML. Interestingly, this tutorial uses <em>TensorFlow Hub</em>, a repository of reusable, pre-trained models. In some ways, this repository provides a central gesture of transfer learning made into a new software platform.</p>

<p>To demonstrate the disconnect and potential bias between the classifying task of the originally trained network and the transfer network applied to a new, related task, consider first of all that the pre-trained model from this repository of models is loaded and configured with just 3 lines of code:</p>

<pre><code>classifier_url =&quot;https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/2&quot; #@param {type:&quot;string&quot;}

IMAGE_SHAPE = (224, 224)

classifier = tf.keras.Sequential([
    hub.KerasLayer(classifier_url, input_shape=IMAGE_SHAPE+(3,))
])
</code></pre>

<p>Secondly, in the beginning of the tutorial, a photograph of Grace Hopper, the famous woman in technology, is fed in as test data after establishing the transfer-learned network. Bias of the original network is shown by the fact that the new network classifies the image as “military uniform” (That Dr. Hopper is wearing) rather than “Grace Hopper” or “Important early computer scientist”, etc.</p>

<p>Following through the tutorial, a pre-trained network is loaded for a second example and its network weights are explicitly set not to be trained further (the whole point of transfer learning is to not have to retrain them):</p>

<pre><code>feature_extractor_layer.trainable = False
</code></pre>

<p>Only, the final layer of the network is removed and a classifying layer (a “classification head”) for recognizing flower species is configured as the penultimate set of nodes.</p>

<pre><code>model = tf.keras.Sequential([
  feature_extractor_layer,
  layers.Dense(image_data.num_classes, activation='softmax')
])
</code></pre>

<p>Until in the tutorial the network is modified further, adding the classification head, the flower detection is not as “accurate”. So in this case, the neural network is potentially unjust until accurate. That the recognition is first inaccurate in this case shows the limitations of transfer learning. But after adding the classification head, the network identifies most of the flowers accurately. Herein lies transfer learning’s philosophical possibility, but this possibility has its own limitations.</p>

<p><strong>Questions</strong></p>

<p>How does the <em>TensorFlow Hub</em> model repository both demonstrate an AI of possibility as well as injustice?</p>

<p>Does transfer learning effect a truer “reuse”, much more powerful than traditional reusable software components and libraries?</p>

<p>If ML/AI can be unjust, despite the role of bias in all learning, is this because it is tied to software and legal policy that impinges upon democracy (by excluding some members of a commonwealth)?</p>

<p>Are there limitations to looking at transfer learning as emergent, given that a learning network, in not being a simulacra of a human brain, could nevertheless be a mirror of “Reason” in a way that would be problematic for 20th Century critiques of Enlightenment (i.e. Adorno, Horkheimer et. al.)?</p>
]]>
        </description>
    </item>
    <item>
        <title>Twitterbot code: JSON simplified codes like natural language</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/62/twitterbot-code-json-simplified-codes-like-natural-language</link>
        <pubDate>Tue, 21 Jan 2020 11:56:22 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>Waliya</dc:creator>
        <guid isPermaLink="false">62@/index.php?p=/discussions</guid>
        <description><![CDATA[<pre><code>* Tittle: @Protestitas' Protestitas
</code></pre>

<ul>
<li>Author: Leonardo Flores</li>
<li>Year: 2017/2018</li>
<li>Link: <a href="https://cheapbotsdonequick.com/source/Protestitas" rel="nofollow">https://cheapbotsdonequick.com/source/Protestitas</a></li>
<li>Language: JavaScript</li>
<li>Snippet:<br />
       "cacerolazoprotesters" :["?#protesterfaces#??", "?#protesterfaces#??", "Ϙ#protesterfaces#??"],<br />
    "featuredslogans" :["#PRslogans#", "#PRslogans#", "#PRslogans#", "#PRslogans#", "#postrickyslogans#"],<br />
        "rickyslogans" : ["¡&#92;#FUERARICKY", "¡&#92;#RICKYRENUNCIA", "¡RICKY RENUNCIA YA", "¡FUERA RICKY", "¡RICKY VETE YA", "¡RICKY DICTADOR", "¡RICKY CORRUPTO", "¡RICKY RENUNCIA AHORA", "¡&#92;#RICKYRENUNCIAAHORA", "¡&#92;#UNNUEVOPUERTORICO"],<br />
        "rickyslogans2" : ["¡RICKY TE BOTAMOS", "¡RICKY PA' FUERA", "¡RICKY NO VUELVAS", "¡FUERA RICKY", "¡&#92;#UNNUEVOPUERTORICO"],<br />
        "postrickyslogans" : ["¡ESTAMOS PENDIENTES", "¡DEJEN EL POLITIQUEO", "¡NO MAS CORRUPCION", "¡BOTAMOS A RICKY Y LOS PODEMOS BOTAR", "¡&#92;#UNNUEVOPUERTORICO", "¡FUERA PIERLUISI", "¡&#92;#RENUNCIA WANDA"],</li>
</ul>

<p>Just have a look and analyse this for me please!!</p>
]]>
        </description>
    </item>
    <item>
        <title>“Master/Slave” Replication in MySQL</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/59/master-slave-replication-in-mysql</link>
        <pubDate>Mon, 20 Jan 2020 21:49:18 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>smorillo</dc:creator>
        <guid isPermaLink="false">59@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Title: Master/Slave Replication<br />
Author/s: Unknown<br />
Language/s: SQL</p>

<p>When I was invited to edit a section of the <a rel="nofollow" href="https://rcstyleguide.com/"><em>Responsible Communication Style Guide</em></a>, one of the terms we added to our “Terms to Avoid” list was "master/slave" to describe primary and secondary nodes. In the volume, we suggest using the alternative “primary/replica”; these are terms I continue to use whenever I come across this replication structure.</p>

<p>The web framework Django and the open-source CMS Drupal formally replaced master/slave with primary/replica back in 2014 (<a rel="nofollow" href="https://code.djangoproject.com/ticket/22667">Conversation in the Django project</a>  and <a rel="nofollow" href="https://www.drupal.org/node/228619">Drupal release notes</a>) Other open-source projects have since then opted for similar alternatives.</p>

<p>The relational database MySQL is among a few open-source projects that have retained “master/slave” terms. In MySQL, master/slave replication refers to configuring a database such that the contents of one database (a “master”) can be automatically copied to others (or “slaves”).</p>

<p>Here are the instructions for configuring the “master” database in a “slave” database:</p>

<pre><code>mysql&gt; CHANGE MASTER TO
    -&gt;     MASTER_HOST='master_host_name',
    -&gt;     MASTER_USER='replication_user_name',
    -&gt;     MASTER_PASSWORD='replication_password',
    -&gt;     MASTER_LOG_FILE='recorded_log_file_name',
    -&gt;     MASTER_LOG_POS=recorded_log_position;
</code></pre>

<p>Once configured, one can start the “slave” by running the following:</p>

<p><code>mysql&gt; START SLAVE;  </code></p>

<p>(<a rel="nofollow" href="https://dev.mysql.com/doc/refman/5.7/en/replication-setup-slaves.html"><em>Source: "Setting Up Replication Slaves", MySQL Documentation</em></a>)</p>

<p>From what I've gathered arguments for and against changing the terminology come down to context: one group argues that since these terms do not refer to the legacy of American slavery nor to an oppressive relationship between humans, these terms should not change (See: “<a rel="nofollow" href="https://www.theregister.co.uk/2018/09/13/redis_master_slave/">On Redis master-slave terminology”</a> by Redis creator Salvatore Sanfilippo). Another group argues that as our understanding of language evolves, so should the terms we use, especially when alternatives may be both inclusive and more accurate (See:<a rel="nofollow" href="https://medium.com/@mikebroberts/let-s-stop-saying-master-slave-10f1d1bf34df"> “Let’s Stop Saying Master/Slave”</a> by Mike Roberts).</p>

<p>With Django and Drupal, community-driven conversations helped precipitate the terminology change. I’ve searched for examples of community conversations from MySQL users where this has been debated, but have not found any as of yet.</p>

<p>Questions to consider:</p>

<ul>
<li>Who should be involved in conversations about updating terminology?</li>
<li>Developers are already accustomed to changes in language paradigms: new programming languages are created, and newly released versions of established programming languages bring changes to syntax and some terms. How can we make the terminology change process (which is left up to individual projects) similar?</li>
<li>While many programming languages are written in English, many developers are non-native English speakers and/or live in countries where English is not the dominant language. Do we need to provide cultural context when communicating terminology alternatives? If so, how do we do this in a way that encourages understanding versus resistance? </li>
</ul>

<p>I welcome your thoughts!</p>
]]>
        </description>
    </item>
    <item>
        <title>New directions in TADS 3: how to enrich user-text communication in text adventures (Code Critique)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/58/new-directions-in-tads-3-how-to-enrich-user-text-communication-in-text-adventures-code-critique</link>
        <pubDate>Mon, 20 Jan 2020 20:09:37 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>KirillAzernyi</dc:creator>
        <guid isPermaLink="false">58@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>I would like to introduce a code I found on a forum - it allows text adventure authors working with TADS 3 to implement new directions. Basically speaking, it allows us to enrich the input language and thus make the user-text communication in TADS adventures more complex.</p>

<p>Author: Pacian (Great Britain) <br />
Language: TADS<br />
Year: 2007</p>

<p>I've been thinking a lot about how imperative and function-oriented the input language of interactive fiction seems to be. Why don't we broaden it to the extent that writing whole pieces of an IF text could be user's commands?</p>

<p>IF is concentrated on actions and pragmatics - which is a paradox, since it's a very descriptive literature and utterly descriptive games. I believe IF doesn't have to be narrative and action-based, and the presented code gives us a tool to make the language of user's commands unlimited. In fact, it could level with the output language of descriptions and narrative that might change relations between author and wreader dramatically - or even reverse.</p>

<p>I believe constant addition of new commands makes role a wreader significantly more complex and contribute more correlation between the playing instances. Can readers become true co-authors of textual adventures?</p>

<p>The code itself:</p>

<pre><code>//A new direction object
forwardDirection: Direction
name = 'forward'
dirProp = &amp;forward
//an integer to sort this direction
//relative to other directions
//we'd give 'backwards' greater than 8000
//for example, so 'forwards' is always listed
//before it
sortingOrder = 8000
;

//the grammar rule for this direction object
//type 'forward' or 'f'
//to try and head in this direction
//(more synonyms preferable)
grammar directionName: 'forward' | 'f' : DirectionProd
dir = forwardDirection
;

/*
* According to actions.t:
*
* &quot;To make it more convenient to use
* directional travel actions as
* synthesized commands, [we] define a set of
* action classes for the specific
* directions.&quot;
*/
DefineAction(Forward, TravelAction)
getDirection = forwardDirection
;

//kill the old 'forward' command.
//The only useful piece of code I found in
//&quot;Relative Direction System for TADS 3&quot; by
//Michael J. Roberts
//(It has been modified)
replace grammar directionName(fore): ' ': DirectionProd ;
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Publication Opportunity: DHQ Minimal Computing (Jan 30)</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/69/publication-opportunity-dhq-minimal-computing-jan-30</link>
        <pubDate>Mon, 27 Jan 2020 14:11:51 +0000</pubDate>
        <category>2020 General</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">69@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>CCSWG participants should consider submitting an abstract to the special issue of Digital Humanities Quarterly on Minimal Computing.  The call covers many of the topics we discuss here and is being edited by past participants Roopika Risam and Alex Gil. DHQ is one of the most preeminent open access journals in the digital humanities and has printed important articles in CriticalCode Studies.  See the call below:</p>

<blockquote><div>
  <p><strong>Calls for Proposals</strong><br />
  <strong>Print Guidelines</strong></p>
  
  <p>Digital Humanities Quarterly Special Issue on Minimal Computing<br />
  Guest editors: Alex Gil (Columbia University Libraries) and Roopika Risam (Salem State University)</p>
  
  <p><strong>Abstracts due January 30, 2020</strong></p>
  
  <p><strong>Special Issue Description</strong></p>
  
  <p>This special issue of Digital Humanities Quarterly will bring together essays and case studies on the promises and limitations of minimal computing from historical, practical, and theoretical perspectives, as well as within the context of specific research projects and their environments.</p>
  
  <p>Minimal computing can be defined as any form of digital or computational praxis done under some set of significant constraints of hardware, software, education, network capacity, power, agency or other factors. Within the context of digital humanities scholarship, minimal computing refers to such computing practices used for teaching, research, and the construction and maintenance of a hybrid -- digital and analog -- scholarly and cultural record.</p>
  
  <p>Broadly construed, our scope is not limited to digital scholarship within the confines of universities and thus includes work undertaken in galleries, archives (institution and community-based), and libraries, as well as in collaboration with communities. In this issue, we strive for equity in gender and particularly encourage submission by women and gender minorities. We further actively seek to include at least one contribution from each of the following geographical areas: Latin America, Africa, and Asia. We are able to accept submissions in English, French, Portuguese, and Spanish.</p>
  
  <p><strong>Suggested Topics</strong><br />
  Topics can include but are not limited to:</p>
  
  <ul>
  <li>Minimal hardware: aged machines, USBs, arduinos, simple circuits, etc.</li>
  <li>Minimal computation: simple scripts, bash, tranductions, etc.</li>
  <li>Static site generation</li>
  <li>Teaching fundamentals of computing tied to subjects in the humanities and the humanistic social sciences</li>
  <li>Forms of making-do in relation to computation: jugaad, hacktivism, DIY</li>
  <li>Technological disobedience, i.e. using technologies in a way they were not intended</li>
  <li>Marginal forms of knowledge and memory production involving computation</li>
  <li>A critique of minimal or minimalist approaches undertaken by choice, rather than by necessity</li>
  <li>Genealogies of minimalist forms of computation</li>
  <li>Case studies on projects that address a multiplicity of costs (environment, bandwidth, access, maintenance, etc) and needs (publishing, remembrance, resistance, etc) with an overall reduction in complexity</li>
  <li>Implications of minimal computing practices for universities, libraries and archives.</li>
  </ul>
  
  <p><strong>Submission Formats</strong></p>
  
  <p>The special issue will consist of two sections: The first section will be reserved for scholarly arguments grounded in history or well argued theoretical work on minimal computing, and the second section will include case studies in the form of specific projects or deep descriptions of environments that pose particular challenges or constraints for digital scholarship and strategic responses to them that incorporate minimal computing practices.</p>
  
  <p>In the first section, we welcome historical perspectives on minimal computing that place contemporary practices in dialogue with multiple documented genealogies; theoretical or strategic pieces that examine socio-technical implications of these practices at scale today; and critical or skeptical voices who are familiar with the implications of minimal computing and the informal discussions and practices that have taken place in the recent past.</p>
  
  <p>For the second section we welcome deep descriptions of projects and environments that include, extend, and complicate minimal computing practices, prompting meditations on difference and imperfect similarity between multiple projects or environments. These case studies should help mainstream audiences understand the granular thinking behind design decisions that respond to specific constraints and challenges.</p>
  
  <p><strong>Submission Details</strong></p>
  
  <p>We ask that you send your abstracts (max. 500 words) to rrisam@salemstate.edu and agil@columbia.edu by January 30, 2020 for a first round of review. Early inquiries are encouraged. We will notify all submitters of the status of their submission in late February. If you are invited to submit a full-length article (~4,000-8,000 words) or a case study (~2500 words), we ask that they be submitted by June 30, 2020.</p>
</div></blockquote>
]]>
        </description>
    </item>
    <item>
        <title>From the introductory chapter: "a job interview"</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/64/from-the-introductory-chapter-a-job-interview</link>
        <pubDate>Wed, 22 Jan 2020 11:48:11 +0000</pubDate>
        <category>2020 Week 1: Introduction to Critical Code Studies</category>
        <dc:creator>jang</dc:creator>
        <guid isPermaLink="false">64@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>I've been prodded to disseminate this a little more widely during Week 1. For reference, the two approaches were as follows:</p>

<pre><code>// Approach 1
function anagram(text) {
  var a = text.split(&quot;&quot;);
  for (var i = 0; i &lt; a.length; i += 1) {
    var letter = a[i];
    var j = Math.floor(Math.random() * a.length);
    a[i] = a[j];
    a[j] = letter;
  }
  return a.join(&quot;&quot;);
}
</code></pre>

<p>and</p>

<pre><code>// Approach 2
function anagram(text) {
  return text.split(&quot;&quot;).sort(function () {return 0.5- Math.random()}).join(&quot;&quot;);
}
</code></pre>

<p>A thing to note about these is that they don't achieve the same thing. I initially posted a demonstration of that <a rel="nofollow" href="https://gist.github.com/jan-g/34bbf97b1f4b1aa885baa5f5b17bbcb4">here</a>.</p>

<h2>Functionality</h2>

<p>Firstly, note that both approaches are biased in terms of the distribution of permutations they create.</p>

<p>There's a simple counting argument here as to the bias in the two approaches. (Both might be suitable for a follow-up question during this hypothetical interview.)</p>

<p>For the first approach, we make <code>n</code> swaps, each picking a target from <code>n</code> elements. There are thus <code>n^n</code> potential paths through the algorithm. However, there are <code>n!</code> distinct permutations. Because the former value doesn't divide cleanly by the latter [example: n = 8, n! = 40320, n^n = 16777216, 16777216 isn't evenly divisible by 40320], the argument is that there <em>must</em> be some bias in the outcome - some "anagrams" crop up more frequently than others. (This is evident even when we're producing anagrams of a simple string like "abc", which you can try by hand.)</p>

<p>For the second approach, any analysis of behaviour needs to rely on the fact that the sorting algorithm is likely to have been picked with a runtime of <code>n . log_2 n</code>. [There are multiple ways to implement a sort, but that's a common behaviour. For n=8, a sort may make 8 . (log_2 8) = 24 comparisons.] Each time the sort algorithm makes a comparison, it'll perform one of two operations: swap, or don't swap. Thus, there are <code>2 ^ (n log_2 n)</code> potential paths through the algorithm - or again, <code>n^n</code>. [For the case n=8, this comes out as 16777216 again.]</p>

<p>However, sorting algorithms try hard to not make comparisons when they "know" what the result would be; thus, this approach produces a much stronger bias in the sampled outcomes. Indeed, some potential anagrams of eight characters don't show up at all during the sample run.</p>

<p>[Assuming the sort function isn't broken, all permutations <em>can</em> turn up - we'd just require far more runs before we expected to see the extreme cases.]</p>

<p>On the question of which of those approaches is "stronger": the first approach produces outputs which are closer to uniform. Additionally, it requires a far smaller change to bring its output to a strictly uniform distribution. The second approach may be "clever", but it's by no means clear that it could be adjusted, should uniformity of output be desired.</p>

<p>If I had to interpret those two samples, I'd say it was much more likely that the second was a reproduction of a trick seen elsewhere, whereas the first seems more likely to be an on-the-spot invention.</p>

<h2>The desirability of uniformity of distribution and the problem statement</h2>

<p>Why desire a uniform distribution? There's certainly a certain symmetrical draw to it. At the other end of the spectrum,  sorting all input characters may suffice - or simply returning the input string. (Where Unicode strings are concerned, "returning the value you've been given" is about the safest thing you can do - see below.)</p>

<p>If the requirement in the problem statement ["An anagram contains all the same characters of the initial string or word in a different order"] is a strong one, then the last option doesn't work - and both of the suggested approaches also have a flaw. However, under those circumstances, we should note that there are inputs where <em>no</em> algorithm can meet a strict interpretation of that requirement. [Examples: any single-character string, or "AAA", etc.]</p>

<p>There may be other, less specific versions of "better," when picking a distribution - for instance, finding letter-orderings which produce more challenging anagrams for a human solver, or ones that embed wry phrases.</p>

<p>Pedantry to one side, however...</p>

<h2>Broader observation</h2>

<p>In typical i18n-blindness, all approaches here don't deal correctly with combining characters and other tricky Unicode features.</p>

<p>I'd also observe that there's a western bias - perhaps even an Anglophone one - to the problem statement. I'm not sure that the notion of an anagram even <em>applies</em> across all the languages that Unicode covers. But the problem there can be found closer to home: if you asked Herr Gauß how many anagrams his surname generated, the answer probably wouldn't be 24. The Unicode consortium offers some partial approaches to dealing with this, but they are by no means comprehensive (and a desire for a comprehensive approach is misplaced, usually arising from an underestimation of how complex the problem space is). Software that deals with human text is notoriously hard to get even close to correct in a cross-cultural fashion. (cf. the question of "how should software handle names?" which has been the subject of a number of writeups.)</p>
]]>
        </description>
    </item>
    <item>
        <title>Code Critiques: Jupyter Notebooks/Taroko Gorge/Flight of the CodeMonkeys</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/65/code-critiques-jupyter-notebooks-taroko-gorge-flight-of-the-codemonkeys</link>
        <pubDate>Thu, 23 Jan 2020 16:24:18 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">65@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>I'm launching this as a code critique thread, but really it's more about tools for studying code. We're always on the lookout for new environs for Critical Code Studies.  We've used Scalar combined with a code repository, Google Docs, Wordpress plugins, and others.  Lately, I've been excited about Google's instantiation of Jupyter Notebooks.</p>

<p>In Colaboratory, code readers can share python code in a Google Doc-like setting.  The code in those docs can be compiled, altered, and run.</p>

<p>I'd like to use this thread as a place to discuss Colaboratory/Jupyter Notebooks as a venue or workspace for Critical Code Studies.</p>

<p><a rel="nofollow" href="https://colab.research.google.com/drive/17dtf2bzWZ59ef34uIfp0f_eHL1mVOP0n" title="Taroko Gorge is here">Taroko Gorge is here</a> for our collective annotation.</p>

<p>For another example, I offer my own interactive fiction <a rel="nofollow" href="https://colab.research.google.com/drive/1abmdaEl3EbfNwkc9pIsqdRhH16RRWyhm" title="Flight of the CodeMonkeys">Flight of the CodeMonkeys</a> as another example of using Colaboratory/Jupyter Notebooks.  In that story, the reader plays by interacting with the code.</p>

<p>I could also imagine using Colaboratory/Jupyter Notebooks to teach lessons in CCS, inviting students to interact with, annotate, and alter code in this shared environment?</p>

<p>What do you think about the possibilities for this tool?  I invite you also to try experiments and share them here.</p>
]]>
        </description>
    </item>
    <item>
        <title>Tips and Tricks</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/55/tips-and-tricks</link>
        <pubDate>Sat, 18 Jan 2020 22:13:34 +0000</pubDate>
        <category>2020 General</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">55@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Thank you for starting new discussions and asking questions. The more you contribute, the better this forum becomes.</p>

<p>Here are a few tips to help you create great discussions:</p>

<p>This forum has a text editor that uses markdown.  Go here for a guide to formatting in <a rel="nofollow" href="https://en.wikipedia.org/wiki/Markdown" title="markdown">markdown</a>.</p>

<p>Proofread. Spelling mistakes, typos, and bad grammar will distract readers from the point you’re trying to make. Vanilla automatically saves drafts as you type. If you’re writing a long post, save it as a draft and come back to it after a few minutes or as long as it takes your brain to forget what you had written.</p>

<p>Use minimal formatting. Overly formatted posts can also distract from the message and it encourages others to do likewise and you end up with a hard to read thread.</p>

<p>Put your post in the right category. The right category can be the one that has a relevant category name or it can be a category where this kind of post is often made.</p>

<p>Use tags. Tags are helpful for others to find keyword related posts. It also helps the site admins get a sense for what topics are popular.</p>

<p>Add an image. Images add visual interest and make your post look great when shared to social networks. You can embed an image using the button bar or you can upload one from your desktop or phone.</p>

<p>Mention others. Credit other members if you are building off their previous comments or if you want to draw them into the discussion. Put the @ before a username to mention someone.</p>

<p>Make the discussion title or question as descriptive as possible. A good discussion title is a short preview of your post and is what gets people to click and read. A well written title is also going to help search engines better index your post which will bring more people into the discussion. For example, instead of ‘Won’t Connect,’ try ‘Help, I’m having problems getting my Acme modem into bridge mode.’</p>

<p>Additionally, you can format any code examples as such by using the "code" option under the paragraph symbol on the editor's toolbar.  You'll find other options under that menu for formatting quoted text and marking "spoiler" content.</p>

<p>As a best practice in threaded discussions, begin your replies with quoted text from the post to which you're responding.  That will keep conversations clear.  Also, link to other discussion and code critique threads whenever appropriate.</p>

<p>Take ownership. Most important of all, take ownership of the discussions that you have created. Respond to comments promptly and thoughtfully. Thank others for commenting on your discussion and help with moderation if things get heated.</p>

<p>For the first time in a CCSWG, you can see the discussions and code critiques from the previous forums in this forum.  However, you cannot continue those discussions on those threads.</p>

<p>We hope you enjoy this online working group!</p>
]]>
        </description>
    </item>
    <item>
        <title>How to Post a Code Critique</title>
        <link>http://wg20.criticalcodestudies.com/index.php?p=/discussion/53/how-to-post-a-code-critique</link>
        <pubDate>Sat, 18 Jan 2020 19:30:00 +0000</pubDate>
        <category>2020 Code Critiques</category>
        <dc:creator>markcmarino</dc:creator>
        <guid isPermaLink="false">53@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Start each code critique as its own thread.  Categorize it as a Code Critique and use (Code Critique) after the name of the code snippet so people can easily find it.</p>

<p>Be sure to include the following:</p>

<ul>
<li>Title</li>
<li>Author/s</li>
<li>Language/s</li>
<li>Year/s of development</li>
<li>Software/hardware requirements (if applicable)</li>
</ul>

<p>Then, place any context and questions you have about the code. It's helpful if you point the conversation in a direction.</p>

<p>Then include your code snippet.  Use the code tags to access our context highlighting.</p>

<p>You can format code by</p>

<ol>
<li>highlighting it in the forum editor</li>
<li>clicking the paragraph or pilcrow (¶) button in the editor bar</li>
<li>selecting "code"</li>
</ol>

<p>...OR by adding three backtick marks ``` on a line directly above your code and on the line directly below as well.</p>
]]>
        </description>
    </item>
   <language>en</language>
   </channel>
</rss>
