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:
- Blocks/procs/lambdas capture local variables
binding
is called (captures current scope)- Continuations are created
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.