DHQ: Digital Humanities Quarterly
Editorial

Rhetorical Strategies of Naming Practices in Code

Abstract

The rhetorical significance of naming practices is widely understood, but it--and many other rhetorical dimensions of language--are often overlooked in the domain of software development, especially in regards to code languages and relevant practices (as demonstrated in file names, functions, variables, and so on). While naming conventions in code are typically recognized as inherently arbitrary, they are also tangled up in numerous networks of community expectations, constraints, and mores, whether organizational or interpersonally social in nature. Given Kenneth Burke's argument for the revealing and concealing influences of terministic screens upon our engagement with the world (by establishing ways of seeing and not seeing), naming conventions in code play an important role in how meaningful invention occurs for human developers and readers of code files. Despite the apparent triviality of such a component of software projects, naming practices shine a light on the goals and values of a programmer in addition to the functional intentions that they might have for the use of a given body of code.

There are only two hard things in Computer Science: cache invalidation and naming things. —commonly attributed to Phil Karlton [Fowler 2009]
[T]he mere act of naming an object or situation decrees that it is to be singled out as such-and-such rather than as something-other. —Kenneth Burke [Burke 1973, p. 4]

Introduction

Among the most seemingly trivial qualities of software code is the set of names given to the components of a given program, including files, functions, and variables. After all, other than file names, it is unlikely that the majority of users will ever explore the source code of that program (assuming that they are even provided access to it). However, it is hardly novel to assert that such names are meaningful; after all, we frequently gain insight from names and naming practices (whether in code or other forms of writing) by virtue of their potential reflection of an author’s values, ideologies, or intended rhetorical action — most notably in regard to the author’s relationships with various audiences. What has been relatively unexplored, and what offers especially notable significance for the rhetorical study of code, is how and why particular rhetorical strategies are enacted through practices of naming in code texts.
There are numerous theoretical perspectives through which naming practices in code might be examined rhetorically, and each contributes to a fuller understanding as to the purposes for which a programmer might use particular naming practices and the kinds of effects that particular names might have on readers of a code text. While this article cannot comprehensively explore the full range of perspectives available through rhetoric, there are several that serve well to illustrate initial paths for further exploration. In this article, I apply a critical framework that brings together classical categorizations of forensic, deliberative, and epideictic rhetoric with Steve Holmes’ (2017) notion of procedural habits. In conversation with one another, the components of this framework allow me to demonstrate how different naming practices in code facilitate particular kinds of phronesis — prudence or practical wisdom [Sachs 2011, p. 209] — that emerge as habits to enact certain rhetorical aims and action among authors and readers alike.
My demonstration involves several brief case studies, each of which serves as an example of phronesis with a different sort of rhetorical aim in mind. The brief declaration and throwing of an exception (named up) demonstrates humor via the forensic nature of naming, meaning an effort to determine what happened and why (in this case, why did the author name the exception up?). An epideictic (praising or blaming) naming occurs in the explicitly named method RichardIsAFuckingIdiotControl, whose author explains his code’s functionality through names that criticize his colleague’s coding decisions. Naming practices’ deliberative qualities — those that work toward a determination of what should or should not be done — can be observed through a metadiscursive and satirical guide to writing “unmaintainable code,” whether that code is meant for others or even the initial author to maintain. Together, these studies illustrate how different habits can promote a variety of rhetorical goals, some less immediately apparent than others.

What’s In a Name?

Any examination of the rhetorical qualities of naming practices in code must acknowledge the metaphorical basis of language. George Lakoff and Mark Johnson (1980) argued that it is often easier for one to understand a potentially complex idea or system when translated into metaphorical terms that contextualize that idea or system into a more easily understood image (e.g., argument as war, time as money or other resource, emotion as orientation). Concisely, they note that “[h]ow we think metaphorically matters” [Lakoff and Johnson 1980, p. 243]. In other words, the metaphors we use to describe and explain complicated ideas have the power to influence how we understand those ideas — the metaphors are neither ornamental nor arbitrary in serving to characterize our conceptualizations of those subjects we discuss. This argument should resonate with rhetoricians, since it is what we choose to communicate as rhetors that reveals to audiences the goals and values that underlie the arguments we make.
Not surprisingly, this sentiment about language’s metaphorical nature is shared by Kenneth Burke (1969), who identified “the use of language as a symbolic means of inducing cooperation in beings that by nature respond to symbols” [Burke 1969, p. 43]. The construction of meaning through language relies on what that language represents — not only to the author of a given statement or message but also to any audiences who encounter it. This reliance is no different in the source code of software than in any conventional form of discourse. Of course, each individual encountering some language approaches it from a unique perspective, with a unique set of values, interests, and motives, and with a unique frame for interpretation of that language. [Burke 1966] referred to this concept as the terministic screen, an orientation toward one’s understanding of the world via their experiences, beliefs, etc. that facilitates some interpretations and constrains others. Burke has famously observed that “a way of seeing is also a way of not seeing” [Burke 1965, p. 49], highlighting the boundaries and limitations, as well as the strengths, of any given perspective. As such, any language use is meaningful in ways that potentially extend beyond any individual reception or interpretation of it. Metaphors tend to perform this extension in some significant and engaging ways, offering insight into the rhetorical contours of an argument through the ways that metaphors ask audiences to consider particular ideas.
This idea of metaphor as rhetorically meaningful has persisted since classical Greece, with Aristotle identifying metaphors as incredibly powerful pillars of rhetorical invention that are employed through examples and enthymemes, incomplete syllogisms that audiences are implicitly invited to complete [Aristotle 1991, I.ii.8]. This long-standing comprehension of the power of metaphor has informed the development of rhetoric and its applications across speaking, writing, and myriad other forms of communication. When used to serve particular ends — to perform various kinds of symbolic action — strategic use of metaphor (and other devices) in language can augment or compromise an argument and the kinds of support it might otherwise gain. Given code’s existence as/through language, the metaphorical dimensions of names in code, as with other rhetorical dimensions of such names, are incredibly significant — especially when it comes to the impact that names and name schemes might have in influencing subsequent programming habits to realize or perpetuate values and ideologies with cascading effects across continued development and potential use of a given program.

Names and Naming in Code

The naming practices of software development, like with any other context for naming something, can be quite complicated and nuanced. Frequently, the metaphors of names in code — such as, for variables, functions, files, etc. — often attempt to reflect an understanding of multiple perspectives, motives, and goals: a) the purpose(s) of the named code for members of the development team; b) relationships between the named code and other bits of code; and c) the potential purpose(s) of the named code for user and any other groups not involved in the code’s development. Depending upon the nature of a given project (such as whether it is developed by an open source, volunteer-based community or by a corporate or proprietary organization), these nuances have the potential to provide confusing or unintended messages to audiences where they intersect or when the development membership changes at a different pace than the stylistic preferences for contributions to that project.
Naming practices within a given project may or may not be dictated or constrained by an explicit or implicit style guide meant to inform involved developers about how they can or should understand naming descriptions and idiosyncrasies within the scope of that project. There may or may not even be a shared sense of how names should rhetorically operate (and there is rarely any express conversation about the “rhetorical” dimensions of such names), which can lead to a wide variety of naming practices by project developers and subsequent discussion about how best, if at all, to address and resolve differences in interpretation of specific naming practices that impact continued development of the project in some way.
Further, this variety is rarely neutral: Names and naming practices can suggest ideological and value-based systems that might reflect the interests, beliefs, or agendas of one or more authors, their organizations, or the cultural contexts in which they live and operate in relation to which the authors, through their code and the names in it, are performing particular identities and roles. As Safiya Umoji Noble (2018) has demonstrated, technological systems like search algorithms often reinforce and reify racist and sexist structures; as code-based components of algorithmic systems, names in code have the potential to perform similarly at a smaller but no less significant scale wherever relevant names appear (noble, 2018). Names, like any other components of code, perform and help realize particular aims when engaged by human readers. Wendy Hui Kyong Chun (2011) notes, “Code does not always or automatically do what it says, but it does so in a crafty, speculative manner in which meaning and action are both created” [Chun 2011, p. 24]. While this argument is primarily directed toward the execution of code, it is just as applicable to code’s composition — especially in regard to how names and naming schemes facilitate or obfuscate various readings of that code’s functionality.
How, then, might we interpret and analyze names and naming practices in code from the perspective of a rhetorician? What can we learn, and how might it help illuminate existing practices as well as to inform future practices? By turning to particular case examples of some common naming practices, we can begin to explore how different purposes or aims might motivate and inform some naming decisions — especially regarding the use of metaphor — as well as how different effects might be achieved through those decisions.

Forensic, Deliberative, Epideictic

According to Aristotle, there are three general contextual aims of classical rhetoric: forensic, to determine what happened in the past; deliberative, to determine what should or should not happen in the future; and epideictic, to celebrate or condemn a subject [Aristotle 1991, I.iii.3–4]. While these aims work well to describe common oratory contexts, they are not necessarily exhaustive in covering all the potential purposes for communicating today. Nonetheless, these classical aims can illustrate initial steps toward a clearer understanding of the rhetorical power and potential in naming practices in code.
For example, code might be employed in an epideictic manner to excoriate a subject, such as one’s employer, colleagues, users, or some relevant principle involved in the development of a given project. As will be examined later, numerous names in the publicly available code snipped for the case of “Richard Is a Fucking Idiot” serves to call attention to the implied failings of the code written by the author’s coworker Richard, which was published initially not by the author but by another colleague who wanted to celebrate the frankness of the code’s descriptive names. Richard — whether real or not — need not be the anticipated reader of this code in its original context, since anyone who might encounter the code (e.g., a future maintainer of the program) is asked to pass judgment on Richard, with the expectation that they will agree with the author’s condemnation of Richard’s abilities, both when reading it and — if a collaborator on the project — when calling its functions as part of continued program development in their own code.
Similarly, we might view many variable names as functioning in a deliberative sense, as they are “meant” to describe the particular functional use(s) of those variables, e.g., timeCounter as a container for measuring the passage of time in some way. While this might seem purely descriptive, in that timeCounter has been named that because it describes the counting of time recorded in the variable, it may have been named timeCounter to be used for such a purpose. Its descriptive nature is thus also a persuasive argument for deliberation, an enthymeme made to developers working on that code so that they will (or feel obligated to) choose to employ the variable primarily, if not solely, for the purpose of counting time, even if the specific reason for counting time may be understood or implemented in different ways by different developers. The phronesis in play reflects a particular kind of habit, a means of prudently supporting both a programming project and its development community through the employment of naming practices that facilitate functionality-related readability and relevant ease of implementing any variables, functions, methods, etc. that rely on interpretations of names via that understood functionality.

Procedural Habits in Naming

The rhetorical decisions regarding names and naming in code are rarely unique and thus tend to reflect common qualities — what might be understood as conventions of code text genres (for more on rhetorical genres in code, see [Brock and Mehlenbacher 2018]). These common qualities might also be described as procedural habits, a term coined by Holmes (2017) to highlight “the specific forms of rhetoric that emerge from dynamic and locally situated repetitions of social, behavioral, and material habits that give rise to meaning and communicative agency in the activities of videogame design, play, and writing about play” [Holmes 2017, p. 10]. While Holmes’ definition is clearly focused on the context of videogames, the term can and does also describe habits beyond those bounds — with software development as a broader and overlapping context in which procedural habits persist. Holmes stresses the need to understand “habit” not only as mechanistic (that is, roughly, as practices we do not consciously think about performing and, in turn, hopefully do not influence our thoughts or behaviors) but also as non-mechanistic:

Non-mechanistic approaches to habit do not allow thought to unmoor itself in transcendence or the free play of signifiers. Rather, these approaches ask instead how thought, rhetoric, and writing are possible at all without the ability of habit to create duration, stability, and repetition in cultural practices, texts, and communication patterns amid an otherwise anonymous flux of Becoming. [Holmes 2017, p. 15–16]

That is, procedural habits, when understood non-mechanistically, serve to facilitate the ethical nature of rhetorical activity by allowing habit to inform how we think, act, and communicate rather than positioning it as a negative, purely mechanical or rote execution of operations. Holmes frames this approach in part through Aristotle’s notion of hexis as “state, disposition, bodily comportment, our habituated ‘second nature’ that guides ethical reasoning” [Aristotle 1991, p. 15]. Viewing habits as non-mechanistic provides a flexibility in analysis and application that allows us to advocate particular habit-related practices of phronesis, the application of practical wisdom that might facilitate more effective rhetorical strategies in particular circumstances, such as in terms of code developed as part of collaborative effort compared to that written by an individual developer for their own unique needs or interests.
What does Holmes’ definition suggest for an exploration of the rhetorical dimensions and effects of names and naming practices in code? Beyond the obvious — that naming practices can be, for many, a kind of procedural habit cultivated both unconsciously and consciously by software developers — it is also that different hexein can inform different states and comportments toward names and how engaging those names might, especially in combination with different orientations toward phronesis, guide other relevant procedural habits of software development and related communication. Further, habits reflect rhetors’ typical and recurrent behaviors, allowing us to understand their work rhetorically as simultaneously idiosyncratic and also representative of their cumulative education and experience with writing and reading code.
For example, common practice tends to involve a proportional decrease in the significance of variable (and, to a lesser extent, function or method) names and their broad readability, with those variables more local in scope often having a name whose meaning or purpose is less immediately clear. That is, a variable or function likely to be used throughout a program (e.g., copyDataToClipboard(data) ) may need to be more descriptive or memorable when a developer encounters it numerous times throughout the code comprising an entire project, while a variable that exists in a limited scope (such as single-letter variables popular as iterators in for loops) may not require longer-term memory of its purpose.
Procedural habits of varying kinds and demonstrating metaphorical connotations that support a range of rhetorical aims (forensic, deliberative, and epideictic), appear across the following three brief case examples that illustrate important considerations regarding rhetorical strategies used in code-related naming practices. First, throw up calls attention humorously to the liminal qualities of naming metaphors — specifically, how forensic rhetoric can emerge through physical metaphors enacted through procedural events. Second, RichardIsAFuckingIdiotControl functions epideictically to excoriate a colleague and their own work practices through a set of methods whose purpose is ostensibly to avoid the mistakes of “Richard’s” practices. Third, the deliberative rhetoric involved in the writing of “unmaintainable” code is explored through a series of sarcastic recommendations — a kind of worst practices guide (whether performed intentionally or not by those whose examples populate the document) — for ensuring that one’s code is impossible for anyone to maintain. Together, these case examples can teach us how the rhetorical work that occurs in code-related naming practices has the potential to be employed even more effectively toward desired or anticipated ends and to reach particular audiences so as to induce productive action, whether for continued development of a program or for its use to effect some sort of change in the world.

Case Example 1: Throw Up

Hans-Erik Nissen (2002) has suggested that most software developers are interested primarily in the functional quality of a specific block of code, its purpose or utility to the program in which it is used. According to Nissen, "[s]oftware practitioners are well aware of the denotational features and largely ignore the connotational features of language. Concepts employed in software products must have unambiguous interpretations in very limited contexts, such as computer programs, database schemas, and so on" [Nissen 2002, p. 86]. Such a position recognizes many corporate development practices, to be sure, but to suggest that developers ignore the connotational features of language — especially for coding purposes — is inaccurate. Even when making use of "built-in" (non-customized) functions and operations, coders are often painfully aware of the connotations of their code, although they may not explicitly make note of those connotations either in the moment of writing or during later navigation and implementation of that code.
For example, the following two lines of Java code describe an explicit exception — that is, an expected disruption of the normal interpretation and execution of code for a given program. Arguably, every variable or function definition is a kind of argument with varying degrees of forensic and deliberative effect, whether to determine what that defined term has been constructed to do, which often appears in code comments that reflect on relevant code, or to make a case in the code itself for its continued use throughout the project through the name itself.
This particular exception is defined by the up variable as an Exception event and by the resulting action that should occur through the throw statement, which removes that exception from the process being executed — the “throw” term loaded metaphorically with a suggestion of forceful removal — usually by ending the program, and the exception alerts developers (or, in some cases, a user) to the specific origin point for that disruption. The throw up exception is articulated and commented on as follows [スーパーファミコン 2009]:
Exception up = new Exception("Something is really wrong.");
throw up; // ha ha
The developer's comment, // ha ha, makes clear the author's awareness of the multiple connotations of the language being used as part of functional code, and the feelings that might arise within a developer for catching an exception that, while anticipated, are likely undesirable, are summed up concisely through the activity (metaphor and computational operation) throw up. If an exception generally indicates a forceful removal via the throw statement, then throw up offers an even more powerful metaphor of regurgitation and expulsion. The problem becomes an unwanted entity to be rejected by the program, a source (and effect) of nausea. While not all developers might approach this joke with a sense of revulsion for the exception being thrown, there might nonetheless be some truth in the affective quality of the metaphor. If developers were generally to ignore the multiple meanings of the language they employ daily through code, we would have to assume they similarly do so in other contexts, i.e., in natural language use. Since very few might ever make this argument, there is no reason to suggest that it occurs within the realm of code.
Further, the most explicitly forensic component of the code is the message that is communicated when the exception occurs: Something is really wrong. There is no hint here of the vomit metaphor in which the message is coded to appear, other than the most general sense of “something wrong” relating to or causing the act of “throwing up” to occur. Even so, the author’s comment — // ha ha — also performs forensically to draw attention to the polysemous nature of the exception’s metaphor. While the output message may only specify that “something” is wrong, the author knows the cause was the code “throwing up” this message. Similarly, those familiar with writing exceptions and identifying their purpose as (either facetiously or seriously) as a kind of vomit-like or vomit-inducing point of frustration as well as problem-specifying event can use this sort of linguistic play to cultivate a sense of community through such a naming practice.

Case Example 2: Richard Is a Fucking Idiot

Many programmers have made extensive use of the flexible possibilities of customization in naming practices to help generate a narrative for themselves and other developers as a means of justifying the purposes toward which they anticipate their code working. Tom Ritter (2010) shared an excerpt of Java code written by another developer who was clearly angry at a coworker during the time of the code's composition. Quoted in part below, the naming practices used in this code pull absolutely no punches in communicating the author's feelings towards the coworker, renamed "Richard" to keep that worker's identity protected [Ritter 2010]:
   public RichardIsAFuckingIdiotControl() {
   MakeSureNobodyAccidentallyGetsBittenByRichardsStupidity();
   }
   private void 
MakeSureNobodyAccidentallyGetsBittenByRichardsStupidity() {
   // Make sure nobody is actually using [the original] method
   MethodInfo m = this.GetType().GetMethod("BindCompany", 
      BindingFlags.DeclaredOnly | BindingFlags.Instance | 
      BindingFlags.Public | BindingFlags.NonPublic);
   [...]
   }
   [...]
   protected override void OnLoad(EventArgs e) {
   if (IsThisTheRightPageImNotSureBecauseRichardIsDumb()) {
      Page.LoadComplete += new EventHandler(Page_LoadComplete);
      Pager.RowCount = GetRowCountBecauseRichardIsDumb();
   }
   base.OnLoad(e);
   }
These functions were authored by Dan McKinley (2009), who revealed his own identity after the code quoted in part above was posted to the popular programming help website Stack Overflow [Ritter 2010], and McKinley explained the above excerpt was part of a larger method declaration named RichardIsAFuckingIdiotControl. This class worked specifically to route data around what McKinley felt was inefficient and resource-intensive code — a sentiment expressed most clearly through his accusations toward the programming skills of coworker "Richard" (a pseudonym, according to [McKinley 2009]). For example, the function IsThisTheRightPageImNotSureBecauseRichardIsDumb(), whose code was called (but not outlined) in the above excerpt, performs a confirmation check on a requested URL before the URL is loaded in order to avoid performing a number of other, potentially unnecessary operations relating to the load (which would then slow down any continued use of the program). This check was added because "Richard" had initially coded the software to execute those potentially unnecessary operations any time a URL was requested. The function's name is clearly not a genuine inquiry but rather a sarcastic evaluation of the preexisting code as being unable to do what McKinley felt it needed to do. That is, McKinley's understanding of how the program's code should work has been complicated — with apparently disastrous results — by Richard’s change to the program's expected functionality.
While one might argue that McKinley's naming scheme is certainly denotative, since his custom function names certainly describe the functional intent of those functions, the scheme also attempts to communicate connotative meaning just as intensely to his audience in an epideictic fashion: The author is not just fixing a problem but demanding that any readers of the code understand — and likely agree with — the amount of anger or frustration he may have felt at having to rework his colleague's efforts. (It should also be noted that this may or may not be an objectively accurate reflection of Richard’s code but rather of McKinley’s interpretation of Richard’s code.) Similarly, McKinley’s naming practice attributes all potential failures of the program here to be the fault of "Richard," at least within the scope of the code: "Richard" is the only idiot identified as potentially being at fault for whatever troubles might befall the user or other developers working on the project. Specifically, McKinley’s naming practice suggests that he needed to MakeSureNobodyAccidentallyGetsBittenByRichardsStupidity with the assumption that user error would be anomalous given the problems that McKinley’s naming practice associated with his coworker's code.
McKinley's adjustments assert a specific deliberative paradigm for how the development organization and its employees should approach their work, an argument for the cultivation of a particular kind of procedural habit that reflects a kind of phronesis regarding the sorts of change that one developer might be able to effect more easily than others when encountering problematic functionality in a colleague’s code. The tone of those adjustments similarly suggests a level of general and contextually-specific programming knowledge that readers — beyond McKinley and Richard specifically — may possess. In excoriating Richard, McKinley’s code might be perceived to either purposely or inadvertently suppress potentially experimental or innovative contributions to the program that could be written by his colleagues. Whether they identify sympathetically with McKinley or with Richard is unknown, but there is an unstated question: if another developer upsets McKinley (or anyone else who might respond similarly), will their shortcomings also be condemned so explicitly throughout a set of documents available to an unknown number of employees at their organization? Or is McKinley’s code here demonstrating a cathartic habit available only through hyperbole and pseudonym, since this sort of practice is — in the contexts of many professional, and especially corporate, organizations — entirely verboten, even if many might feel the sentiment is warranted.
In addition, Richard's name itself comes to serve as an example of synecdoche, a rhetorical device that refers to some concept or entity by way of one of its parts (or, as in this case, the part by way of the whole). Here Richard's code is the point of contention, and Richard's nature as a "fucking idiot" is demonstrated only through the code to which McKinley has alluded with his workarounds. Our exposure to Richard exists only through these changes made to his code — we do not experience Richard's alleged “mistakes” in the program source. Rhetorically, the audience is asked to consider Richard (the person) indirectly through the lens of Richard's body of code and directly through the lens of McKinley's body of code about Richard's body of code, with all the value statements made about Richard’s code intertwined with the proposed change in functionality that McKinley applied to it.
McKinley is able to direct his frustration with the code toward its author, and his appeal is effective for those who might have experienced similar irritation with coworkers or collaborators of questionable skill or knowledge (but, conversely, may be less effective for those who may be less comfortable with their own programming skills or knowledge of the organizational "flow" related to working with McKinley or with Richard). Whether or not this frustration or irritation is well-founded, of course, varies from case to case — but that's not the point. Instead, the potential for an author to communicate it at all is the important detail; the developer's impetus is inscribed and preserved in the program for all future contributors to witness.

Case Example 3: How to Write Unmaintainable Code

This following case “example” is not a single excerpt of source code but rather a document about code, a satirical take on practices that implement embarrassing or frustrating naming schemes in code. This metadiscursive document reflects another sort of orientation toward the cultivation of emergent procedural habits in software development and which may reflect a commonly recognized sense of phronesis present in their execution. Roedy Green (2017) provides, through this satirical guide, a relatively thorough examination of the laughable decisions made by some programmers that, deliberately or otherwise, “ensure” that their work is impossible to build on or otherwise maintain. While Green's organization of their larger work, with “Naming” as a subsection, suggests that naming practices make up only a small part of the means by which someone could construct an unmaintainable program, the entire essay is pervaded with observations that relate to the habits of naming practices in a variety of ways, from ambiguity or obfuscation that decreases readability to eschewing company standards and style requirements in favor of personal preferences.
Much of Green's advice relates to considerations of names in code as representatives of particular metaphorical structures or as subversions of those same structures. For example, Green jokes that it is important to prefix class instance names with some sort of indicator that the developer recognizes it is an object, such as o_apple or obj_apple. This approach, Green notes, “show[s] that you're thinking of the big, polymorphic picture” [Green 2017].That is, the attention paid to clarifying details in this particular habit — which might normally require no clarification — suggests not that an authoring programmer understands the purpose (the “big, polymorphic picture”) of a name as reflecting some sort of understood utility but rather that the author perceives those clarified details as constituting the significant metaphorical dimensions of a name, likely to the detriment of its future maintainers. What benefit for the author and any other developers arises from such a name? The nomination of each class instance as an object, such as with a prefix, does not guarantee that the remainder of the name descriptively reflects, in any way, the suggested purpose of that particular object, especially if it was instantiated with some specific goal in mind that might be more meaningful to other readers. Green elaborates on a similar point elsewhere: “Under no circumstances, succumb to demands to write a glossary with the special purpose project vocabulary unambiguously defined” [Green 2017]. The statement hyperbolically lambasts the principle of clearly communicating to one’s reader the scope and purpose of the naming scheme(s) used for a particular project, as that would invite the reader to understand those schemes more fully and, theoretically, to participate in the use and proliferation of those schemes in further development of the project at hand.
Similarly, languages like Java provide developers with the opportunity to (or the demand that) variable types are named twice, e.g. String[] myString = new String[]; However, as Green notes, it is possible to complicate this approach by specifying a variable as a different data type than expected: Bubblegum b = new Bubblegom(); (notice the spelling difference in gom vs. gum). This sort of naming can be even more obvious or pronounced, but for Green it seems to be the subtle, hard-to-spot, change that has the most significant effect in regard to creating work for a future developer. After all, clearly visible differences stand out, and Green’s argument appears to be most interested in the sorts of stylistic naming activities that elude easy recognition. As Green notes, “Your code should not look hopelessly unmaintainable, just be that way. Otherwise it stands the risk of being rewritten or refactored” [Green 2017] [emphasis in original]. That is, the more overt or recognizable the “bad” practice, the easier it is for an audience to address productively.
As a result, names as representatives of metaphor have the potential to derail those metaphors — or force a drastic reconsideration of them — when multiple developers approach a particular project with different metaphors in mind. This situation is unavoidable; one can never ensure that any reader will ever engage a text in exactly the same way as any other, sometimes even when there are closely aligned expectations about the text; c.f. [Fish 1982]. However, the freedom provided to every developer to name the components of their code however they desire (regardless of those names' helpfulness or clarity) supports a view of naming as extremely powerful practice, since it imparts some indication of interpreted significance to a reader through the names chosen by an author. In some cases, an author’s choices are constrained by the authors of an overarching system, e.g. the labels used for particular data types (such as String vs. Object vs. var), specific operations (such as throw in throw up), or semantic tags in markup (such as <blockquote> or <cite>) to suggest particular kinds of tagged content; see [Beck 2016] for a discussion of the rhetorical differences between human and machine interpretative contexts. These metaphorical practices are, of course, procedural habits formed over time by exposure to the particular habits of others and imitated or rejected to varying degrees for just as varied reasons. In Green's case, these habits can result in decisions that appear infuriating or laughably painful to the reader, but they nonetheless all demonstrate the developer-as-namer to be a crucial nexus in a network of meaningful development-related communication.

The Rhetorical Nature of Development Practices

The broad range of possibilities for naming practices — such as those briefly explored in the three case examples above — appropriately reflects the broad range of possibilities for communicating meaning in any mode or medium. Whether such practices are viewed as being significant for the purposes of rhetorical study, the fact remains that developers' values and perspectives on their code — as well as those of organizations, systems, and structures exerting varying degrees of overt and implicit influence on those developers — are transmitted through the names they provide for their work along with any goals they intend to suggest the code should achieve. In addition, those same values inform the way(s) their code is designed to function, both internally (with other functions, sometimes written by other developers) and externally (through the expression of the overall program in which that code operates). When a number of developers' individual practices converge for the creation of a large-scale program, these rhetorical influences often override the sets of standards and best practices to which the involved developers are expected to adhere. As a result, the contextual and situated qualities of rhetorical meaning-making underlying both the code and its expressive program become visible, providing rhetoricians with an excellent opportunity to study the creation of that software as well as the range of actions it facilitates through its use.
Among the most intriguing such programs are the open-source software projects developed by volunteers from across the globe, since there is potentially a wide range of sociocultural factors introduced to, and influencing, any number of components of those projects' code. These factors can demonstrate both a diverse set of interests and perspectives as well as any efforts to transform that diversity into consistency (of code style, functional logic, and/or cultural expression); in both respects, the developers' rhetorical awareness can have a significant impact on future development and use of a given project. While there may be little explicit discussion among programmers about the meaningful nature of the naming practices they participate in, whether individually or collectively, there can be little doubt that the names chosen reflect and influence how a particular code project continues to be developed and applied. This is not to suggest that naming practices are any less important in corporate or proprietary contexts, as demonstrated by the “Richard Is a Fucking Idiot” case example above, as they are (by their very nature) much less open, if open at all, to critical scrutiny from third parties.
The procedural habits implicit in various naming practices in code are worthy of further scrutiny, not only to understand more fully how they operate rhetorically in an immediate or obvious sense but also how they enact potentially prejudicial or oppressive ideologies, whether those ideologies are recognizable to or intended by any of the authors involved in a particular project’s naming practices or in naming practices surrounding coding itself, e.g. the pejorative term “code monkey” frequently used to describe an unskilled programmer or low-status programming position [Easter 2020]. Similarly, offensive language was so prevalent in code uploaded to the open-source repository GitHub during the early 2010s [Romano 2013] that the site’s administrators have since developed and enforced explicit policies on banning and preventing such language on the site [GitHub 2022]. More recently, the administrators for GitHub and a number of software projects have argued against the conventional use of “master” to describe the primary version or branch of a software repository, seeking to replace the term with “main” to reduce the use of racially charged and historically loaded terms and to support the Black Lives Matter movement [Cimpanu 2020].
By attending more closely to how names and naming practices perform rhetorically in a range of significant ways, we — scholars, programmers, teachers, and citizens — can work not only to communicate more effectively how code does and could operate but also how that code contributes to the development of a more inclusive and considerate world.

Acknowledgments

This article was originally developed for, but not published in, the short-lived open-source journal experiment Push: Research & Applied Theory in Writing with Source. The author thanks Push’s founder Karl Stolley for that opportunity and is grateful to Chris Lindgren, Steve Klabnik, and Ward Cunningham, who offered valuable feedback for the earliest iterations of this article [Brock et al. 2012].

Works Cited

Aristotle 1991 Aristotle. (1991) On rhetoric: A theory of civic discourse (G. Kennedy, Trans.). New York: Oxford University Press.
Beck 2016 Beck, E. (2016) “A theory of persuasive computer algorithms for rhetorical code studies”, enculturation, 26. Available at: https://enculturation.net/a-theory-of-persuasive-computer-algorithms.
Brock and Mehlenbacher 2018 Brock, K. and Mehlenbacher, A. R. (2018) “Rhetorical genres in code”, Journal of Technical Writing and Communication, 48.4, pp. 383-411. https://doi.org/10.1177/0047281617726278
Brock et al. 2012 Brock, K, et al. (2012) “Submission: Brock, ‘Naming practices in code as rhetorical strategies’ #2.” GitHub. Available at: https://github.com/cwcon/push/pull/2.
Burke 1965 Burke, K. (1965) Permanence and change. Berkeley and Los Angeles: University of California Press.
Burke 1966 Burke, K. (1966) Language as symbolic action. Berkeley and Los Angeles: University of California Press.
Burke 1969 Burke, K. (1969) A rhetoric of motives. Berkeley and Los Angeles: University of California Press.
Burke 1973 Burke, K. (1973) Philosophy of literary form. Berkeley and Los Angeles: University of California Press.
Chun 2011 Chun, W. H. K. (2011) Programmed visions: Software and memory. Cambridge: MIT Press.
Cimpanu 2020 Cimpanu, C. (2020) “GitHub to replace ‘master’ with alternative term to avoid slavery references”, ZDNet. Available at: https://www.zdnet.com/article/github-to-replace-master-with-alternative-term-to-avoid-slavery-references/.
Easter 2020 Easter, B. (2020) “Fully human, fully machine: Rhetorics of digital disembodiment in programming”, Rhetoric Review, 39.2, pp. 202-215.
Fish 1982 Fish, S. (1982) Is there a text in this class?: The authority of interpretive communities. Cambridge, MA: Harvard University Press.
Fowler 2009 Fowler, M. (2009) “TwoHardThings”, martinFowler.com. Available at: https://www.martinfowler.com/bliki/TwoHardThings.html.
GitHub 2022 GitHub. (2022) “GitHub hate speech and discrimination”, GitHub Docs. Available at: https://docs.github.com/en/site-policy/acceptable-use-policies/github-hate-speech-and-discrimination.
Green 2017 Green, R. (2017) “Unmaintainable code”, Canadian Mind Products: Java & Internet glossary. Available at: https://www.mindprod.com/jgloss/unmain.html.
Holmes 2017 Holmes, S. (2017) The rhetoric of videogames as embodied practice: Procedural habits. New York: Routledge.
Lakoff and Johnson 1980 Lakoff, G. and Johnson, M. (1980) Metaphors we live by. Chicago: University of Chicago Press.
McKinley 2009 McKinley, D. “From the annals of dubious achievement”, Dan McKinley: Math, Programming, and Minority Reports (2009). https://mcfunley.com/from-the-annals-of-dubious-achievement.
Nissen 2002 Nissen, H. E. (2002) “Challenging traditions of inquiry in software practice”, in Dittrich, Y., Floyd, C., and Klischewski, R. (eds.), Social thinking-software practice, Cambridge, MA: MIT Press, pp. 69-90.
Noble 2018 Noble, S. U. (2018) Algorithms of oppression: How search engines reinforce racism. New York: NYU Press.
Ritter 2010 Ritter, T. (2010) “// Code sanitized to protect the foolish”, Stack Overflow. Available at: http://stackoverflow.com/a/184673.
Romano 2013 Romano, A. (2013) “Code Search reveals developer community’s hidden bigotry”, Daily Dot. Available at: https://www.dailydot.com/society/github-code-search-racism-sexism-bigotry/.
Sachs 2011 Sachs, J. (2011) “Glossary”, in Aristotle (J. Sachs, trans.), Nicomachean ethics, Indianapolis and Cambridge: Focus Publishing, pp. 201-212.
スーパーファミコン 2009 スーパーファミコン. (2009) “Exception up = new Exception(“Something is really wrong.;””), Stack Overflow (2009). Available at: https://stackoverflow.com/a/549611.