To reify means to make something abstract or implicit into something concrete and explicit. In computing, reification transforms virtual or lazy structures into real, materialized data.

Etymology and Core Meaning

From Latin res (thing) + facere (to make) = “to make into a thing”

Reification is the act of treating an abstract concept as if it were a concrete, real thing. In programming contexts, it means:

  • Converting lazy evaluation to eager evaluation
  • Materializing virtual structures into memory
  • Making implicit state explicit

Reification in Virtual Machines

In YARV and other VMs, reification commonly refers to making execution frames concrete:

Normal execution (frame lives on call stack):

def calculate
  x = 10
  y = 20
  x + y
end
 
calculate  # Frame exists temporarily, then destroyed

Reified frame (frame made concrete/permanent):

def make_closure
  x = 10
  lambda { x + 1 }    # Lambda captures 'x', frame must be reified
end
 
proc = make_closure   # Frame can't be destroyed - proc needs it!
proc.call            # Still accessing original frame's 'x'

When a closure captures variables, YARV must reify the frame - move it from the temporary call stack to permanent heap memory.

Stack to Heap Transformation

Reification often involves moving data from stack to heap:

Before reification (normal call):
┌──────────────┐
│  Call Stack  │
│  ┌────────┐  │
│  │ Frame  │  │ ← Temporary, destroyed on return
│  └────────┘  │
└──────────────┘

After reification (captured by closure):
┌──────────────┐         ┌──────────────┐
│  Call Stack  │         │     Heap     │
│              │         │  ┌────────┐  │
│              │────────→│  │ Frame  │  │ ← Permanent, GC managed
│              │         │  └────────┘  │
└──────────────┘         └──────────────┘

The frame is “reified” - made into a concrete heap object.

Lazy vs Eager: A Reification Pattern

Reification converts lazy (deferred) computation to eager (immediate):

Lazy (not reified):

# Range doesn't create array
range = 1..1_000_000
 
# Values generated on demand
range.each { |n| puts n }  # Memory efficient

Eager (reified):

# Array created immediately - reification!
array = (1..1_000_000).to_a  # All values materialized in memory
 
array.each { |n| puts n }    # Memory intensive

Calling to_a reifies the range into a concrete array.

Reification in Different Contexts

1. Closures and Captured Variables

def outer
  x = "captured"
  -> { puts x }    # Closure captures 'x', outer's frame reified
end
 
closure = outer    # Frame reified to heap
# outer has returned, but frame still exists
closure.call       # Prints "captured"

2. Call Site Optimization

Some VMs reify call site information:

# First call: lookup method, reify (cache) result
object.method_name
 
# Later calls: use reified (cached) lookup
object.method_name  # Faster - uses cached/reified data

The method lookup is reified into an inline cache.

3. Continuations

Continuations reify the entire call stack:

# Capture current execution state (reify it)
callcc do |continuation|
  # 'continuation' is reified execution state
  continuation.call  # Can resume this state later
end

The call stack is reified into a continuation object.

4. Lazy Collections

# Lazy enumerator (not reified)
lazy = (1..Float::INFINITY).lazy.map { |n| n * 2 }
 
# Reify first 10 elements
lazy.take(10).to_a  # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

to_a reifies the lazy computation.

Performance Implications

Reification has costs:

Benefits:

  • Enables closures and first-class functions
  • Allows deferred computation to be materialized
  • Makes implicit state inspectable/debuggable

Costs:

  • Memory allocation (stack → heap)
  • Garbage collection overhead
  • Slower access (heap vs stack)
  • Complexity in VM implementation
# Fast: no reification needed
def simple
  x = 10
  x + 1
end
 
# Slower: frame must be reified
def with_closure
  x = 10
  -> { x + 1 }    # Reification overhead
end

Reification in YARV

YARV reifies frames when:

  1. Blocks/procs/lambdas capture local variables
  2. binding is called (captures current scope)
  3. Continuations are created
  4. eval needs access to current scope
def example
  x = 42
 
  binding          # Reifies frame for inspection
  eval("x")        # Needs reified frame
 
  -> { x }         # Reifies frame for closure
end

Each of these operations requires the frame to be made concrete and permanent.

Philosophical Note

Reification in programming mirrors a philosophical concept: treating abstract ideas as concrete objects. In virtual machine architecture, we take abstract execution states (frames, continuations) and make them into concrete, manipulable objects.

This is powerful - it enables features like closures and continuations - but it comes with the cost of making the implicit explicit.