What is a cell in the context of an interpreter or compiler?
closures, compiler-construction, interpreter, python, rust
Solution
In Python, `cell` objects are used to store the free variables of a closure.
Let's say you want a function that always returns a particular fraction of its argument. You can use a closure to achieve this:
def multiplier(n, d):
"""Return a function that multiplies its argument by n/d."""
def multiply(x):
"""Multiply x by n/d."""
return x * n / d
return multiply
And here's how you can use it:
>>> two_thirds = multiplier(2, 3)
>>> two_thirds(7)
4.666666666666667
How does `two_thirds` remember the values of `n` and `d`? They aren't arguments to the `multiply` function that `multiplier` defined, they aren't local variables defined inside `multiply`, they aren't globals, and since `multiplier` has already terminated, its local variables no longer exist, right?
What happens is that when `multiplier` is compiled, the interpreter notices that `multiply` is going to want to use its local variables later, so it keeps a note of them:
>>> multiplier.__code__.co_cellvars
('d', 'n')
Then when `multiplier` is called, the value of those outer local variables is stored in the returned function's `__closure__` attribute, as a tuple of `cell` objects:
>>> two_thirds.__closure__
(<cell at 0x7f7a81282678: int object at 0x88ef60>,
<cell at 0x7f7a81282738: int object at 0x88ef40>)
... with their names in the `__code__` object as `co_freevars`:
>>> two_thirds.__code__.co_freevars
('d', 'n')
You can get at the contents of the cells using their `cell_contents` attribute:
>>> {v: c.cell_contents for v, c in zip(
two_thirds.__code__.co_freevars,
two_thirds.__closure__
)}
{'d': 3, 'n': 2}
You can read more about closures and their implementation in the Python Enhancement Proposal which introduced them: PEP 227 — Statically Nested Scopes.
Problem
Python code objects have an attribute `co_cellvars`. The documentation to PyPy's bytecode interpreter often uses the term Cell. Among other langauges, Rust provides a Cell datatype. Googling suggests they relate to closures somehow. What is a cell, in the context of a programming language implementation? What problem do cells solve?