[Python-ideas] And now for something completely different
Terry Reedy
tjreedy at udel.edu
Thu Sep 18 05:54:18 CEST 2008
Cliff Wells wrote:
> You can accomplish this to some degree by using lambda,
You can do it completely as far as I know.
> but I'd much prefer something indicated in the function signature
> than in the calling code.
Given Python's nature as a compiled dynamic language, indications are
really needed in both caller and callee, as at present: pass a function
and call it. Without an explicit indication at the call site, the
compiler would have to compile both direct evaluation and function
object creation and the code to select between them at runtime according
to an attribute of the function resulting from evaluation of the
presumed function expression. This would slow *all* function calls,
which are slow enough already. Also, one could not tell what objects
get passed to a function without knowing the signature in detail, making
code harder to read.
There is already a way to be flexible without magical arg object
switching and with only exceptional need for del/lambda.
def iff(cond, if_result, else_result):
if cond:
if hasattr(if_result, '__call__'): return if_result()
else: return if_result
else:
if hasattr(else_result, '__call__'): return else_result()
else: return else_result
for i in [0,1,2]:
print("I gave you %s gold piece%s." % (i,iff(i==1, '', 's'))) #3.0
#prints (imagine a typical RPG game)
I gave you 0 gold pieces.
I gave you 1 gold piece.
I gave you 2 gold pieces.
One only needs the wrapper if the object to be returned is a function
example -- iff(cond, lambda: math.sin, lambda: math.cos)(x)
or if the expression needs to be guarded by the condition because it
would otherwise be invalid (iff(x, lambda x=x: sin(x)/x, 1) -- this
might work without the default arg, but might have scope problems)
or if it would take a long time.
But many conditional values are constant or quick to evaluate and the
short-circuiting is not needed. Many of the exceptions might better be
defined in functions anyway.
def sin_or_cos(cond,x):
if cond: return math.sin(x)
else: return math.cos(x)
def sin_over_x(x):
if x: return math.sin(x)/x
else: return 0
Terry J. Reedy
More information about the Python-ideas
mailing list