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.
The basic idea is to just specify that those arguments must be zero-argument callables, and only call them if you actually need them.
The rest of this message is something that just occured to me that could make that style 'prettier' (if lambda looks as ugly in function calls to you as it does to me). It's completely untested, though :)
First, some utility functions to convert values and functions with arguments to a lazily evaluable function:
def lazy(x, *args, **kwds): """Executes x(*args, **kwds) when called""" if args or kwds: return lambda : x(*args, **kwds) else: return x # No arguments, so x must be callable by itself
def lazyval(x): """Allows passing a normal value as a deferred argument""" return lambda : x
def lazycall(x, *args, **kwds): """Executes x(*args, **kwds)() when called""" return lambda : x(*args, **kwds)()
For literals, their constructor provides a zero-argument callable equivalent:
[] -> list (,) -> tuple {} -> dict 0 -> int "" -> str 0L -> long
And the operator module provides a way to delay most operations:
import operator lazy(operator.mul, x, y) # Delayed x * y lazy(operator.itemgetter(i), x) # Delayed x[i] lazy(operator.attrgetter("a"), x) # Delayed x.a lazycall(lazy(operator.attrgetter("a"), x)) # Delayed x.a()
(That last example is why I added lazycall() to the utility functions)
Then you can write a function called 'select':
def select(selector, *args, **kwds): if kwds: return kwds[selector]() else: return args[selector]()
And one called 'either' (since 'if' is taken and using 'select' would get the true case and the false case back to front):
def either(pred, true_case, false_case): if pred: return true_case() else: return false_case()
And use them as follows:
select(selector, list, lazyval(mylist), lazy(eval, expr, globals(), locals())) select(selector, c1 = list, c2 = lazyval(mylist), c3 = lazy(myfunc, a, b, c)) either(condition, guarded_operation, lazyval(default_case))
Huh. I think I like the idea of lazy() much better than I like the current PEP 312. There must be something wrong with this idea that I'm missing. . .
Cheers, Nick.
-- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.skystorm.net -- http://mail.python.org/mailman/listinfo/python-list