Codicality and materiality

 
A Material History of Bits
Jean-François Blanchette

In this paper, I argue that bits cannot escape the material constraints of the physical devices that manipulate, store, and exchange them. Such an analysis reveals a surprising picture of computing as a material process through and through.

Knoespel and Zhu (2008) suggest the popular characterization of cyberspace as “an ethereal escape from the filthy, hopeless ‘meat’ world” is inherited from a Cartesian dualism that posits a strict dichotomy between language (spirit) and the material world. Moving beyond such “romantic notions of immateriality,” they suggest computing systems are characterized by a “continuous materiality,”

“ … a wide spectrum of materiality activated by a hierarchy of codes that moves from ‘lower’ machine code to ‘higher’ readable computer languages and to codes in general (structural, legislative, social, cultural, etc.). Each level of code engages natural language and the physical world in different ways, varying from the shifting voltage of computer circuits to our everyday activity. Altogether, the hierarchy of codes constructs a field of diverse materiality that is continuous and interconnected.” (p. 236)
 

Continuous materiality accounts for the materiality of computing on several levels: through the immanence of embodied experience in language, manifested by the dual registers through which code operates. Instructions to machines (open window, cut and paste) are also apprehended by humans via the metaphorical function of language. Even while programmers mostly operate within strictly positivists conceptions of language, computer code creates relationships among multiple symbolic systems, those necessary to move the cogs of the machine, and those necessary for those operations of the machine to be situated within language, and thus, social order. At the same time, multiple kinds of computer code co-exist within the computer, each potentially mediating among different codes pertinent to different social systems.

Knoespel, K. & Zhu,, J. (2008). Continuous materiality through a hierarchy of computational code. Théorie, Littérature, Epistémologie, 25, 235-247.

(from Graduate Course Proposal: Materiality in the Digital Humanities)

‘The Transversality of New Materialism’

And not in the least place, those pre-modern philosophers such as Duns Scotus, Lucretius and the whole Stoic tradition, whose work is not (that) effected by dualist thought, are being read like never before. The richness of these philosophies had, by and large, been forgotten in dualism dominated modernism and postmodernism.
 

~~~

 

Codicalism dissolves the separation between languages (e.g., programming) and substrate. Substrate matters again.

New Materialism dissolves the separation between humans and nonhumans. Things matter again.

 

Following “Vibrant Matter: A Political Ecology of Things” (Jane Bennett), “Planning Matter: Acting with Things” (Robert A. Beauregard), maybe there should be “Virtuous Matter: The Ethics of Things”.

 

Philip Thrift

Advertisements

Vibrant materialism

 

ref. Vibrant Matter: a political ecology of things

(My comment: This short book is a fun-to-read antidote to antimaterialism.)
 

Vibrant matter, zero landscape
An interview with Jane Bennett

Within a short genealogy of materialism – from Epicurus to the most recent accounts by Bruno Latour – “What kind of materialist are you…”

JB: I would have to be Michel Foucault to be able to offer even a short genealogy of materialism. Instead, I will name the two pragmatic problems that pushed me in the direction of affirming (and, to the extent that Vibrant Matter is a polemic, preaching) “vital materialism”. The first was the intensification of an alarming trend in American public culture wherein a rise in the invocations by politicians of otherworldly powers (the Judeo-Christian “Almighty” combating “forces of evil”) was paired with the positioning of violence and torture as legitimate tools of state. (William Connolly speaks here of an “evangelical-capitalist resonance machine” and I think that Lucretius, Voltaire, Nietzsche, Foucault and other iconoclasts of piety are right to remind us of the gruesome history of some variants of theism in the West.) This combination moved me to speak on behalf of an ethical outlook that was non-theistic and non-teleological (at least in the strongest sense of telos), to proclaim the possibility that an undesigned order of materiality could nevertheless possess the impressive, dynamic, incalculable, awesome and awful qualities elsewhere ascribed to God or Geist or “the human spirit”. It is materiality that is wondrous.

The second problem was ecological destruction, or the globalizing political economy devoted to extraction and exploitation, waste, commodification, human imperialism and winner-take-all. I am a vital materialist who sees positive, pro-green potential in raising the profile of the fact that any human “I” is itself made up of “its” – of a vast array of originally and to varying degrees persistently nonhuman elements, such as bacteria, metals, ambient sounds, the “trains” of images of other bodies, etc. Here I have been inspired by the straightforwardness of Bruno Latour’s rejection of the anthropocentric bias in the social sciences.

 


cf.
1. youtube.com/watch?v=q607Ni23QjA
2. punctumbooks.com/titles/feeling-things
3. backdoorbroadcasting.net/2013/10/a-feeling-for-things-a-conversation-around-the-work-of-jane-bennett
4. philosophyinatimeoferror.com/2010/04/22/vibrant-matters-an-interview-with-jane-bennett

 

~~~

The ‘new materialism’ is the most common name given to a series of movements in several fields that criticise anthropocentrism, rethink subjectivity by playing up the role of inhuman forces within the human, emphasize the self-organizing powers of several nonhuman processes, explore dissonant relations between those processes and cultural practice, rethink the sources of ethics, and commend the need to fold a planetary dimension more actively and regularly into studies of global, interstate and state politics.

from mil.sagepub.com/content/41/3/399.abstract

 

also

New Materialism: Interviews & Cartographies

Planning Matter: Acting with Things
by Robert A. Beauregard

Toward a New Materialism: Matter as Dynamic
by Rachel Tillman

What’s New about New Materialism?
A Special Session at MLA 2015

 
(This Note is a reaction to the not-so-latent antimaterialism in We’re Doomed. Now What?)
 

Philip Thrift

The Procedural-Computational-Programmatic Turn

 

The shift I am proposing, from mere logical analysis to modeling of phenomena, requires procedural literacy. Although procedural literacy is not emphasized in philosophy, there are some philosophers who are procedurally literate, and the future spoils will go to those who join them.

Models, Models, and Models
Gregory Wheeler
philsci-archive.pitt.edu/9500/1/Models.pdf

 
 

For humanities scholars, artists and designers, computer programming can seem a narrow technical skill, a mere familiarity with the latest fads and facility with the latest jargon of the computer industry. In this view, programming has almost no connection with theoretical and philosophical considerations, with concept and aesthetics, with a design focus on human action and interpretation. This attitude is often adopted by new media scholars and practitioners, including game designers and game studies scholars, who may assume that the “mere” technical details of code can be safely bracketed out of the consideration of the artifact. In this paper I argue that, contrary to this view, procedural literacy, of which programming is a part, is critically important for new media scholars and practitioners, that its opposite, procedurally illiteracy, leaves one fundamentally unable to grapple with the essence of computational media. In fact, one can argue that procedural literacy is a fundamental competence for everyone, required full participation in contemporary society, that believing only programmers (people who make a living at it) should be procedurally literate is like believing only published authors need to learn how to read and write; here I will restrict myself to the case of new media scholars and practitioners.

Procedural Literacy: Educating the New Media Practitioner
Michael Mateas
press.etc.cmu.edu/node/205

 
 

cf.

Procedural Literacy: Problem Solving with Programming, Systems, & Play
Ian Bogost
bogost.com/downloads/I.%20Bogost%20Procedural%20Literacy.pdf

Why Coding Is Your Child’s Key to Unlocking the Future
wsj.com/articles/why-coding-is-your-childs-key-to-unlocking-the-future-1430080118

 

~~~

 

Computational philosophy uses computational techniques to assist in philosophical discovery and provide evidence for philosophical positions that may not be easily found using traditional philosophical methods alone. It involves an array of techniques including standard computer programing, artificial intelligence, computer modeling, agent-based modeling, network analysis and ontology construction. Its philosophical targets cut across almost all branches of philosophy, including metaphysics, epistemology and axiology, along with various specialized domains such as the philosophies of science, mind, technology, social and political philosophy, the history of philosophy, etc.

digitalhumanities.evansville.edu/computational%20philosophy

cf.

CEPE-IACAP 2015

 
 

Philip Thrift

HUM

 

The Mathematical Universe Hypothesis — or MUH — says that ‘mathematics precedes matter’.

The reverse of MUH is HUM (Hyletic Universe Model): ‘matter precedes mathematics’.

That makes more sense. If it weren’t for matter there would be no mathematicians to create mathematics!


cf.
Phenomenology Without Correlationism: Husserl’s Hyletic Material
Patrick Whitehead

“Phenomenology may emphasize hylé – that is, material; or it may emphasize nous – the world as it appears to or is transformed by consciousness.”

The “hyletic” phenomenology of “Phenomenology Without Correlationism: Husserl’s Hyletic Material” is like codicalism: The substrate is the hyle that is “understood” by languages.

 

Philip Thrift

The beyond-Turing universe

 

The “conventional” view

“Every finitely-realizable physical system can be simulated efficiently and to an arbitrary degree of approximation by a universal model (quantum) computing machine operating by finite means.”
 

leaves out the possibility of beyond-Turing computing:

Every realizable physical system can be simulated efficiently and to an arbitrary degree of approximation by a hyper-/quantum-/biomolecular-computing (HQB) machine.
 
 

cf.
DNA as basis for quantum biocomputer
Spectral gaps may reveal beyond-Turing computing
Aspects of Molecular Computing

 
 

Philip Thrift

Cartesianists, Computationalists, and Codicalists

 

Cartesianists – There is a material-physical realm and a nonmaterial-nonphysical realm.

Computationalists* – There is one realm made of, or is identical to, or arises from informational-mathematical-computational structures.

Codicalists – There is only a material-physical realm that we have varying degrees of successful access to, or knowledge of via informational-mathematical-computational languages.

 

* These are “conventional” computationalists. The “natural” computationalists though think the Church-Turing thesis is wrong, and there is some sort of beyond-Turing computing afoot in human consciousness/brains.

It could be the case that a conscious devices can only be built/synthesized out of particular materials (like the particular biochemicals that make up our brain.

Quantum computing plays a role in photosynthesis. Perhaps likewise in consciousness. But you don’t need conscious brains to create “reality”. Maybe plants are enough. 🙂

 
 

Philip Thrift

Rhizomatic programming

 

  • A rhizome ceaselessly establishes connections.
  • Any point of a rhizome can be connected to any other and must might be.
  • A multiplicity is, in the most basic sense, a complex structure that does not reference a prior unity.
  • If you break a rhizome it can start growing again on its old line or on a new line. Connections are constantly breaking and reforming.
  • The rhizome is like a map and not a tracing.

Principles for Rhizomatic Thinking, Jenny Mackness

 

The rhizomatic programming paradigm is introduced in this Note by examples written in Python*. Rhizomatic programming is defined here as a heterogeneous, multigrain parallel paradigm, and a variant of reactive, actor, and dataflow programming. It derives its conception and terminology from Grenander’s Geometries of knowledge, A Calculus of Ideas, and other pattern-theoretic works. [Rhizomatic programming is the culmination of the Calideas programming framework: See Notes 33,35,39.]

* All code is written and executed in Python version 3.5.

 

‘Term’inology

A configuration is heterogeneous collection of nodes, created by generators (or parametric node factories) connected by bonds. Each node can have multiple inputs and multiple outputs. Each input to a node flows from a bond, and each output from a node flows into a bond. A bond is connected to at most one input and at most one output. Data objects, or terms flow via bonds from node to node asynchronously. Each node processes its input data and bonds transfer node outputs to other nodes. A snapshot of a running configuration at a particular time step is an image. A stream of images is a cine. An equivalence class of images formed by a group of generator parameter settings is a pattern. A genre is an equivalence class of cines.

Terms (objects, or molecules) are transported via bonds though a configuration (a rhizomic structure), are processed by nodes which produce transformed and new terms. The bond values are effectively steams of terms which represent the state of the configuration.

 

Nodes and generators

A node function is a function with two arguments. The two arguments — conventionally In and Out — are lists representing input and output bond values: In represents the input buffers and Out represents the output buffers of the node.

Example. A node function with 2 inputs and 1 output:

def nodePlus(In , Out):
     Out[0] = In[0]+In[1]
     return True
 

A node is a dictionary, return by the function node:

def node(Function, NumberInputs, NumberOutputs, Type):
#   node execution type: ALL_IN_AUTO, ALL_IN_MANUAL, ONE_IN_AUTO, ONE_IN_MANUAL
   return {'function': Function, 'inputs': [None]*NumberInputs, 'outputs': [None]*NumberOutputs, 'type': Type}
 

There are (currently) four types of nodes that specify when a node can execute:

  • 'ALL_IN_AUTO': All input buffers are filled, and input buffers are cleared automatically when the node function returns.
  • 'ALL_IN_MANUAL': All input buffers are filled, but input buffers must be cleared (with the clear or clear_all function.
  • 'ONE_IN_AUTO': Same as ‘ALL_IN_AUTO’ but the node executes when at least one input buffer is filled.
  • 'ONE_IN_MANUAL': Same as ‘ALL_IN_MANUAL’ but the node executes when at least one input buffer is filled.

Example. A node with 2 input buffers and 1 output buffer:

adder = node(nodePlus, 2, 1, 'ALL_IN_AUTO')
 

Note: An empty buffer is represented by None.

A generator is a node factory: it takes arguments (called generator parameters) and produces a new node.

Example. A generator that takes a Scale parameter and produces a node that inputs 2 values representing a 2-D point x and outputs 2 values representing the end point of a 45-degree vector based at x and length Scale:

def gen45deg(Scale):
   def node45deg(In,Out):
      # sqrt(2)/2 = 0.70710678
      Out[0] = In[0]+0.70710678*Scale
      Out[1] = In[1]+0.70710678*Scale
      return True
   return node(node45deg, 2, 2, 'ALL_IN_AUTO')

Here’s the generator of nodes utilizing the nodePlus function:

def genPlus( ):
   def nodePlus(In, Out):
       Out[0] = In[0]+In[1]
       return True
   return node(nodePlus, 2, 1, 'ALL_IN_AUTO')

And another that performs the print function:

def genPrint( ):
   def nodePrint(In, Out):
      print(In[0])
      return True
   return node(nodePrint, 1, 0, 'ALL_IN_AUTO') 

Some node utilities:

def all_full(Buffers):
   if Buffers:
      for b in Buffers:
         if b == None:
            return False
   return True

def all_empty(Buffers):
   if Buffers:
      for b in Buffers:
          if b != None:
             return False
   return True

def not_all_empty(Buffers):
   if Buffers:
      for b in Buffers:
          if b != None:
             return True
   return False

def empty(Buffers):
   if Buffers:
      for i in range(0,len(Buffers)):
         Buffers[i] = None
   return True

def clear(Buffers, b):
   Buffers[b] = None
   return True

def clear_all(Buffers):
   return empty(Buffers)

def execute(Node):
   inputs = Node['inputs']
   outputs = Node['outputs']
   type = Node['type']
   if (type == 'ALL_IN_AUTO'):
      if all_full(inputs) and all_empty(outputs):
         Node['function'](inputs, outputs)
         empty(inputs)
         return True
   elif (type == 'ONE_IN_AUTO'):
       if not_all_empty(inputs) and all_empty(outputs):
         Node['function'](inputs, outputs)
         empty(inputs) 
         return True
   elif (type == 'ALL_IN_MANUAL'):
      if all_full(inputs) and all_empty(outputs):
         Node['function'](inputs, outputs) 
         return True
   elif (type == 'ONE_IN_MANUAL'):
      if not_all_empty(inputs) and all_empty(outputs):
         Node['function'](inputs, outputs)
         return True
   return False
 

Bonds

A bond is a dictionary, returned by the function bond:

def bond(From, To, Value):
   return {'from': From, 'to': To, 'value': Value}

def transfer(Bond):
    input = Bond['to']         #  (node,  index)
    output  = Bond['from']  # (node, index)
    input_value = None
    output_value = None
    if output != None:
          output_value = output[0]['outputs'][output[1]]
    if input != None:
           input_value = input[0]['inputs'][input[1]]
    if  output_value != None and Bond['value'] == None:
           Bond['value'] = output_value
           output[0]['outputs'][output[1]] = None
    if input != None and input_value == None and Bond['value'] != None:
            input[0]['inputs'][input[1]] = Bond['value']
            Bond['value'] = None
    return Bond['value']

The first two arguments of bond are pairs: From for the output node and index, and To for the input node and index. Value is the initial bond value (which could be None).

 

Configurations

A configuration of formed from generator created nodes and bonds:

def config(Nodes, Bonds):     # (Nodes, Topology) in future
    return { 'nodes': Nodes, 'bonds': Bonds }

def runfig(Config, N):
   nodes = Config['nodes']
   bonds = Config['bonds']
   for n in range(0,N):
      for g in nodes:
         execute(g)
      for b in bonds:
         transfer(b)
   return True
 

Diagrammatic representation

A diagrammatic representation of a configuration (rhizomatatc program) consists of bonds (represented by identifiers in brackets [ ]), generator nodes (represented by bold identifiers), and flows (represented by arrows labeled by an input or output identifier).

[ bond_1_0 ]
     ↓0
                    [ bond_1_1 ]   →1 adder1
     ↓0
[ bond_2_1 ]
     ↓1
                    [ bond_2_0 ]   →1 adder2
     ↓0
[ bond_3_0 ]
0
printer1
 

Example code

# examples

def gen45deg(Scale):
   def node45deg(In,Out):
      # sqrt(2)/2 = 0.70710678
      Out[0] = In[0]+0.70710678*Scale
      Out[1] = In[1]+0.70710678*Scale
      return True
   return node(node45deg, 2, 2, 'ALL_IN_AUTO')

def genPrint( ):
   def nodePrint(In, Out):
      print(In[0])
      return True
   return node(nodePrint, 1, 0, 'ALL_IN_AUTO') 

def genPlus( ):
   def nodePlus(In, Out):
       Out[0] = In[0]+In[1]
       return True
   return node(nodePlus, 2, 1, 'ALL_IN_AUTO')


# tests

vector = gen45deg(3.0)
printer0 = genPrint( )
printer1 = genPrint( )
b0 = bond(None, (vector,0), 0.0)
b1 = bond(None, (vector,1), 0.0)
b2 = bond((vector,0), (printer0,0), None)
b3 = bond((vector,1), (printer1,0), None)
test0 = config([vector, printer0, printer1], [b0, b1, b2, b3])
runfig(test0, 10)

adder1 = genPlus( )   
adder2 =  genPlus( )
printer1 = genPrint( )
bond_1_0 = bond(None, (adder1,0), 1)
bond_1_1 = bond(None, (adder1,1), 2)
bond_2_0 = bond(None, (adder2,0), 3)
bond_2_1 = bond((adder1,0), (adder2,1), None)
bond_3_0 = bond((adder2,0), (printer1,0), None)
twoAdders = config([adder1, adder2, printer1],  [bond_1_0, bond_1_1, bond_2_0, bond_2_1, bond_3_0])
runfig(twoAdders, 10)



# examples

def genPass( ):
   def nodePass(In, Out):
      Out[0] = In[0]
      return True
   return node(nodePass, 1, 1, 'ALL_IN_AUTO')


# tests

g_1 = genPass( )
g_2 = genPass( )
g_3 = genPass( )
g_4 = genPass( )
g_5 = genPrint( )
b_1 = bond(None,  (g_1,0), 'o')
b_2 = bond((g_1,0), (g_2,0), 'l')
b_3 = bond((g_2,0),  (g_3,0), 'l')
b_4 = bond((g_3,0) , (g_4,0), 'e')
b_5 = bond((g_4,0),  (g_5,0), 'H')
hello = config([g_1, g_2, g_3, g_4, g_5], [b_1, b_2, b_3, b_4, b_5])
runfig(hello, 10)


# examples

def genDup( ):
   def nodeDup(In, Out):
      Out[0] = In[0]
      Out[1] = In[0]
      return True
   return node(nodeDup, 1, 2, 'ALL_IN_AUTO')

def genPlusPass( ):
   def nodePlusPass(In, Out):
       Out[0] = In[1]
       Out[1] = In[0]+In[1]
       return True
   return node(nodePlusPass, 2, 2, 'ALL_IN_AUTO')

# tests

adder1 = genPlusPass( )
printer1 = genPrint( )
duper1 = genDup( )
b1 = bond((adder1,0), (duper1,0), 1)
b2 = bond((adder1,1), (adder1,1), 1)
b3 = bond((duper1,0), (adder1,0), None)
b4 = bond((duper1,1), (printer1,0), None)
fib = config([adder1, duper1, printer1], [b1, b2, b3, b4])
runfig(fib, 25)



# examples

def genConst(Value):
   def nodeConst(In, Out):
      Out[0] = Value
      return True
   return node(nodeConst, 0, 1, 'ALL_IN_AUTO')


# tests

g1 = genConst('Hey')
p1 = genPrint( )
b1 = bond((g1,0), (p1,0), None)
c1 = config([g1,p1], [b1])
runfig(c1, 10)


#examples

# nodeMerge has 3 inputs and 2 outputs.
# The first two inputs are streams to be merged, and the third is an item that is given priority.
# If there are two items to be merged, one is output and the second is output on Out[1], which will appear in In[2].
def genMerge( ):
   def nodeMerge(In, Out):
      if (In[2] != None):
         Out[0] = In[2]
         clear(In, 2)
         return True
      elif (In[0] != None):
         Out[0] = In[0]
         if (In[1] != None):
            Out[1] = In[1]
            clear(In,1)
         clear(In, 0)
         return True
      elif (In[1] != None):
         Out[0] = In[1]
         clear(In, 1)
         return True
      return True
   return node(nodeMerge, 3, 2, 'ONE_IN_MANUAL')

# tests

m1 = genMerge( )
c1 = genConst('a')
c2 = genConst('b')
p1 = genPrint( )
b1 = bond((c1,0), (m1,0), None)
b2 = bond((c2,0), (m1,1), None)
b3 = bond((m1,0), (p1,0), None)
b4 = bond((m1,1), (m1,2), None)
merge = config([m1,c1,c2,p1], [b1,b2,b3,b4])
runfig(merge,20)

m1 = genMerge( )
x1 = genPass( )
c1 = genConst('a')
c2 = genConst('b')
p1 = genPrint( )
b0 = bond((c1,0), (x1,0), None)
b1 = bond((x1,0), (m1,0), None)
b2 = bond((c2,0), (m1,1), None)
b3 = bond((m1,0), (p1,0), None)
b4 = bond((m1,1), (m1,2), None)
merge = config([m1,x1,c1,c2,p1], [b0,b1,b2,b3,b4])
runfig(merge,20)

m1 = genMerge( )
x1 = genPass( )
x2 = genPass( )
c1 = genConst('a')
c2 = genConst('b')
p1 = genPrint( )
b = bond((c1,0), (x1,0), None)
b0 = bond((x1,0), (x2,0), None)
b1 = bond((x2,0), (m1,0), None)
b2 = bond((c2,0), (m1,1), None)
b3 = bond((m1,0), (p1,0), None)
b4 = bond((m1,1), (m1,2), None)
merge = config([m1,x1,x2,c1,c2,p1], [b, b0,b1,b2,b3,b4])
runfig(merge,20)


# examples 

def genConstAlt(Value, Frequency):
   def nodeConstAlt(In, Out):
      if (In[0] == Frequency):
         Out[0] = Value
         Out[1] = 0
         return True
      #  Out[0] = '?'
      Out[1] = In[0]+1
      return True
   return node(nodeConstAlt, 1, 2, 'ALL_IN_AUTO')

# tests

m1 = genMerge( )
c1 = genConstAlt('a', 5)
c2 = genConst('b')
p1 = genPrint( )
b0 = bond((c1,1), (c1,0), 0)
b1 = bond((c1,0), (m1,0), None)
b2 = bond((c2,0), (m1,1), None)
b3 = bond((m1,0), (p1,0), None)
b4 = bond((m1,1), (m1,2), None)
merge = config([m1,c1,c2,p1], [b0, b1,b2,b3,b4])
runfig(merge,55)
 

Philip Thrift