Code as Material Culture

One hot summer in France I found myself excavating Neanderthal bones in Les Pradelles, a Mousterian reindeer butchering site north of the Dordogne. I was young and restless and relentlessly curious, and the idea of spending long, impassioned days in a gravel pit analyzing and interpreting objects seemed like a great idea at the time.

It was also during this time I first became interested in — edit: obsessed with — material culture.

In University, I took a variety of social science courses that allowed me to think about the symbolic components of complex organizational systems. Everything from Mayan death rituals to modern American foodways, Haitian voodoo to Northwest Coast Native Art. Anthropology became an approach to problem solving — a way of thinking about domains and their structure — and of “man is an animal suspended in webs of significance he himself has spun” (Clifford Geertz, Interpretation of Cultures).

Material culture was different, like Japanese Death Poetry or Cat Stevens. I loved seeing the physicality of a culture embodied in an object from the past. To me that object was everything: it was a keyhole, it was metaphor, it was technology, it was language, it was life.

Hand Axes and Early Technology

One day while excavating in my rocky quadrant thinking about Lorca and his gorgeous “Lament for Ignacio Sanchez Mejias,” I found something. It was recognizably man-made, a tool perhaps, appearing somewhat out of place in the context of sandstone rubble. Snapping out of the depths of that July afternoon, I took out my own tool, a black flat paintbrush, and worked the bristles swiftly around the object. I meticulously unearthed it from the warm dirt. Before removing the object, I sketched it in media res to identity its original place within the grid.

I let out an exhale. I looked down at the object for a long time, forgetting about the dirt that was making interesting indentation patterns under my knees.

I took this object to the basin at the threshold of the excavation site. Washing my object in water was somewhat of a religious experience. Here in my hands was a hand axe. A tool crafted by someone on the fringes of humanness. The last time this axe was held, I guessed, it was likely by a Neanderthal. I marveled at this object, turning it around in my hand under the afternoon sun. I examined with detail the denticulated edges of the biface. Moving my fingers over the edges, palming the object with force, I let it slip perfectly into the curves of my inner palm.

Biface Profiles - early forms of material culture

Biface profiles – early forms of material culture

To me this tool was recognizably material culture. It told a story. It had a presence that was re-adopted — catalogued by myself and reclaimed as an artefact of the site — and yet its past was the evolutionary blueprint behind its creation. It was beautiful.

Material Culture 

What is material culture? Material Culture is the physical embodiment of culture in the objects and architecture that culture has made. Material culture studies is the cross-disciplinary field analyzing the relationships between people and their objects: the making, history, preservation, and interpretation of objects. Material culture theory (and practice) draws from the humanities and social sciences, from museology, history, archaeology, historic preservation, folklore, and the like. Anything from momental buildings and architectural elements, Artificial Intelligence, Cosmopolitan magazine, shoes, hair brushes. All can be considered material culture.

Code as Material Culture

As I continue onward in my journey as a developer, I often reflect on my time at Les Pradelles. How does material culture relate to code? What does a JSON object and a hand axe have in common? What can object oriented design tell us about human relationships? How does programming and the machines we create and flex give us insight into human logic?

How does this:

haiku

Dada(ist) Haiku: a haiku generator app from Wikipedia articles. Designed by Anna Rasshivkina, Liz Kalina and myself.

Relate to this:

Note: this app produces nonsensical Dada(ist) haikus which are (sometimes) as delightful as they are random

Occasionally this app produces Dataist haikus which are as delightful as they are random.

Excavating a Codebase

We can imagine code as material culture because it is application architecture. It is built by humans, modified by humans, preserved by humans. It is both physical and object-oriented. You can hold code in your hand. You can touch code, inspecting it in the console of a website with your cursor. As with any tool, it is adapted to the needs of its users over time.

JavaScript, for example, owes its incredibly light framework to its haphazard birth as a programming language in May 1995. Developed by Brendan Eich in just 10 days some 20+ years ago, the language itself has evolved over time, entering a new realm of standardization and innovation. JavaScript frameworks and libraries like Node.js, Backbone.js, Underscore.js, Handlebars.js, etc., have added complexity and fullness to the stack. Like the development of biface tools across the Palaeolithic landscape, our material culture reflects a movement towards efficiency and standardization.

Coding encodes human logic. This is exciting across multiple programming languages because there are so many different ways of solving the same problem. Viewed in this way, methods and frameworks become lenses into human logic. When I am familiarizing myself with a codebase, as I did in Les Pradelles, I often ask myself the following questions:

  1. What is the logic of production of this tool?
  2. How do humans experience and interact with this technology?
  3. What purpose does this technology serve?
  4. Where am I in the codebase, stack, etc., and how does this part relate to the object itself?

Humans and their Machines

When we imagine code as material culture we can also think of it it as a lens into the current state of affairs of technological production. Technology is, after all, as much about human relationships as it is about machines. If a hand axe demarcates a type of human cognition some 40,000 years ago, what about code today? What does this mean if 85% of “producers” of code are male? And if this is the case, how does this effect our experience with technology?

In my next post I’ll discuss this touching on the documentary CODE: Debugging the Gender Gap.

JavaScript for Rubyists

Sometimes the journey from Ruby to JavaScript can feel like diving into a swimming pool of parenthesis and semicolons.

There — I said it.

But JavaScript is really important — and really pervasive. In fact, 78.2% of the top one million websites across the world wide web use JQuery — a JavaScript library and language framework — to render powerful online web applications.

Travelling the Information Superhighway

Travelling the Information Superhighway

Writing JavaScript as a Rubyist can sometimes burn us as noobie programmers because its syntax is so unforgiving. Remembering to include semicolons and brackets when we are dealing with blocks, returns statements before variable declarations, variable scope (whether local or global) , etcetera and etcetera and etcetera, may feel initially overly-declarative — not to mention frustrating. Don’t worry, n00b, there’s hope.

Let’s look at a few examples.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;; JavaScript ;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Behold JavaScript. One look at JavaScript and we see a language abound in semicolons and weird syntax. But no, this is not Brainfuck. Not quite — at least.

Semicolons are abundant in JavaScript because of a process called statement chaining, which only really means executing two statements on one line.

var coolPhrase = “gnik drazil eht ma I";
coolPhrase = coolPhrase.split(“”).reverse().join(“”); coolPhrase = coolPhrase.toUpperCase();
// => “I AM THE LIZARD KING”

Semicolons are also used to delineate and define statements. For example:

var myFace;                     // variable declaration 
i = 1000000;                    // value assignment 
i = i + 14;                     // value assignment 
i++;                            // value assignment 
var numOfMyProblems = 99;       // value assignment 
console.log(“I am a genius”);   // function call 

JavaScript for Rubyists

JavaScript’s framework is incredibly light. This owes itself to it’s unique origins as a functional programming language. Interestingly, JavaScript was originally developed in 10 days in May 1995 by Brendan Eich. Read about the history of JavaScript here

In Ruby there are many ways to solve a problem because Ruby graciously gives us a bunch of methods to break down a problem. In JavaScript, this is not the case. When I first approached JavaScript, pouring over each function and semi-colon gingerly, I started wondering: “where are all the JavaScript language features?” Where is the .map, the .each, .reduce — for god sakes, the .find!? — allowing for easy and efficient iteration over collections of objects.

The horror when I thought: will I really have to use “for” loops ad infinitum to iterate through problems?

Underscore

Enter Underscore. Underscore is a utility-belt JavaScript library that gives the Rubyist a whole mess of useful functional programming helpers — more than 100, in fact — to keep in your arsenal. From the Underscore API: 

“[Underscore] is the answer to the question: “If I sit down in front of a blank HTML page, and want to start being productive immediately, what do I need?” … and the tie to go along with jQuery‘s tux and Backbone‘s suspenders.” 

Lets see the brilliance of Underscore in action. (Seriously — prepare to freak out). 

Collection Functions
(arrays, objects, array-like objects)

Each in Ruby

Recall using each when working with non-transformative functions. If these functions embody a complex object, this is usually linked to some sort of action. For example: iterating through a list of names (or emails) and interpolating a greeting (or emailing that list in an action mailer).

list_names = ["Holly", "David Bowie", "Lizard King"]
list_names.each {|name| puts “Hello #{name}!”)
=> Hello Holly!
=> Hello David Bowie!
=> Hello Lizard King!

Each in JavaScript

Underscore gives us a pretty sexy each equivalent which we can use to iterate over a list of elements.

_.each(list, iteratee, [context]

Taken in an example:

_.each([1,2,3], function(num){console.log(num);});
// 1
// 2
// 3
[1, 2, 3]

Super cool.

Map in Ruby

Recall using map in Ruby for transformative functions.

a = [1,2,3] 
irb > a.map {|num| num * num }
=> [1, 4, 9]

Cool beans! We know and love map in Ruby when iterating through collections of objects. 

Map in JavaScript

Underscore syntax of map is very similar to its Ruby counterpart.

_.map(list, iteratee, [context])

Let’s look at an example.

a = [1,2,3]
 _.map([1,2,3], function(num){ return num * 9;});
 // [9, 18, 27]

Nonsense-amounts of awesome.

Working With Arrays
(Lists of Elements and Objects)

First in Ruby

We know first as a powerful Ruby method which returns or plucks the first element [with index 0] of an array. For example:

gross_words = ["moist", "bumpkin", yourMom"]
gross_words.first
=> "moist"

First in JavaScript

Surprise, surprise. First in JavaScript is very similar.

_.first([5, 4, 3, 2, 1]);
=> 5

Identity Functions
(Uncovering the Status of Objects) 

Identity functions allow us to uncover the status of objects. This is important in programming — and especially in JavaScript — because objects can be conceptually different if they are nil, NaN, or null. Studying the Underscore API I was struck by the applicability of these functions in JavaScript:

isNaN

syntax: _.isNaN(object)
Returns true if object is NaN

_.isNaN(NaN);
=> true
isNaN(undefined);
=> true
_.isNaN(undefined);
=> false

isNull

syntax: _.isNull(object)
Returns true if the value of object is null.

_.isNull(null);
=> true
_.isNull(undefined);
=> false

isUndefined

syntax:  _.isUndefined(value)
Returns true if value is undefined.

_.isUndefined(window.missingVariable);
=> true

 

Resources