Lazy evaluation where the value of something is calculated the first
time it is needed but accessed from some storage if it is needed again.
I do this all the time. It's not very hard and doesn't require any
extra language support, but I would like for there to be an
authoritative list of type slots (autopromise_ops).
import operator
def promise(thunk):
x = []
def promised():
if not x:
x.append(thunk())
return x[0]
return promised
autopromise_ops = [x for x in dir(operator) if x.startswith('__')]
autopromise_ops += ['__getattribute__', '__call__', '__str__', '__repr__']
autopromise_ops += ['__getattr__', '__setattr__', '__delattr__']
def autopromise(thunk):
p = promise(thunk)
d = {}
for op in autopromise_ops:
def bindhack(op=op):
return lambda self, *a, **kw: getattr(p(), op)(*a, **kw)
d[op] = bindhack()
return type('autopromise', (), d)()
def test():
lis = []
def thunk():
lis.append('ran thunk')
return 'value'
s = autopromise(thunk)
p = s * 30
assert p == 'value' * 30
p = s * 10
assert p == 'value' * 10
assert lis == ['ran thunk'] # Just once
print 'autopromise sanity test passed'
An autopromise object is good almost everywhere the real one would be,
and usually the only way to tell the difference is to call id or type
on it. The main exception is when the thunk returns a builtin type
(like a string or int) and you want to pass it to a builtin function
that expects a particular type (this would also apply to Python
functions that break duck typing on purpose, but those would just be
getting the breakage they deserve).