Reification

24 Jun 2016

Reification (in programming) is the process of deciding to model something as a thing - often, in object oriented programming, this means modeling it as an object.

For example, imagine a little ballistics simulation:

# constants
FRICTION = 0.01
GRAVITY = 0.1

# globals
pos_x = 100
pos_y = 100
vel_x = 2
vel_y = -2

def update():
  global pos_x, pos_y, vel_x, vel_y
  pos_x += vel_x
  pos_y += vel_y
  vel_x -= FRICTION * vel_x
  vel_y += GRAVITY

We have four global integers. To demonstrate reification, we could decide to make the position an object.

class Position:
  def __init__(self, initial_x, initial_y):
    self.x = initial_x
    self.y = initial_y

# constants
FRICTION = 0.01
GRAVITY = 0.1

# globals
pos = Position(100, 100)
vel_x = 2
vel_y = -2

def update():
  global pos, vel_x, vel_y
  pos.x += vel_x
  pos.y += vel_y
  vel_x -= FRICTION * vel_x
  vel_y += GRAVITY

We can say a couple things about reification. Observe that replacing pos_x and pos_y with pos.x and pos.y was not very hard. In general, if there are variable names with a common prefix or suffix, you can use that to think of new reification moves.

Another thing, is that reification moves code complexity - in this case, you might say it increases code complexity, but notice that importing pos from global scope is a tiny bit briefer than importing both pos_x and pos_y. In non-toy examples, this kind of shrinkage can actually outweigh the new class and make reification a net decrease in code size.

Of course, we don't have to bundle the two position integers together, we could instead bundle the two x-related integers together:

class MomentumVar:
  def __init__(self, initial_position, initial_velocity):
    self.pos = initial_position
    self.vel = initial_velocity
  def update(self):
    self.pos += self.vel

# constants
FRICTION = 0.01
GRAVITY = 0.1

# globals
x = MomentumVar(100, 2)
y = MomentumVar(100, -2)

def update():
  global x, y
  x.update()
  y.update()
  x.vel -= FRICTION * x.vel
  y.vel += GRAVITY

Tutorials on object orientation, and even some programmers who have been in industry for a while, sometimes behave dogmatically. Objects are something like an organizational scheme, a system of files and folders, imposed on in-principal-procedural underlying elements, like functions and variables. Knowing that there are many different alternatives, and even many different reasonable alternatives, can help evolve code from one state to another.

Usually the barrier to evolving code is imagination. Specifically, the programmers cannot imagine enough states in between the beginning and the goal to make the steps (from intermediate state to intermediate state) small.

class MomentumVar:
  def __init__(self, initial_position, initial_velocity):
    self.pos = initial_position
    self.vel = initial_velocity
  def update(self):
    self.pos += self.vel

class Rock:
  def __init__(self, x_pos, y_pos, x_vel, y_vel):
    self.x = MomentumVar(x_pos, x_vel)
    self.y = MomentumVar(y_pos, y_vel)
  def update(self):
    x.update()
    y.update()
    x.vel -= FRICTION * x.vel
    y.vel += GRAVITY

# constants
FRICTION = 0.01
GRAVITY = 0.1

# globals
rock = Rock(100, 100, 2, -2)

def update():
  global rock
  rock.update()