late evaluation of function arguments (WAS: expression form of one-to-many dict?)

Steven Bethard steven.bethard at gmail.com
Sun Dec 19 15:44:27 EST 2004


Mike Meyer wrote:
> Personally, I'd love a language feature that let you create a function
> that didn't evaluate arguments until they were actually used - lazy
> evaluation. That lets you write the C ?: operator as a function, for
> a start.

You can fake it with generator expresions:

.   >>> class C(object):
.   ...     def __init__(self, x):
.   ...         print x
.   ...
.   >>> def unpack(x):
.   ...     try:
.   ...         x, = x
.   ...     except TypeError:
.   ...         pass
.   ...     return x
.   ...
.   >>> def f(x):
.   ...     print "f"
.   ...     print unpack(x)
.   ...
.   >>> f(C("created"))
.   created
.   f
.   <__main__.C object at 0x01140790>
.   >>> f(C("created") for _ in [1])
.   f
.   created
.   <__main__.C object at 0x0114F810>

Of course, the syntax here isn't great -- create a generator expression 
that yields only one item, and call unpack on all function arguments to 
convert them from generators to items as necessary...  But it does 
achieve the stated goal -- with the GE, the C object isn't created until 
unpack is called from inside f.

Faking ?: this way could look like:

.   >>> def cond(test, true_exp, false_exp):
.   ...     if test:
.   ...         return unpack(true_exp)
.   ...     else:
.   ...         return unpack(false_exp)
.   ...
.   >>> cond(True,
.   ...      (C("true exp") for _ in [1]),
.   ...      (C("false exp") for _ in [1]))
.   true exp
.   <__main__.C object at 0x0114F730>
.   >>> cond(False,
.   ...      (C("true exp") for _ in [1]),
.   ...      (C("false exp") for _ in [1]))
.   false exp
.   <__main__.C object at 0x0114F8B0>

I don't know how often this is really necessary, but as it is 
implementable in current Python, if you really liked it, you could argue 
for some syntactic sugar for the construct...

Steve



More information about the Python-list mailing list