[Python-ideas] And now for something completely different

Terry Reedy tjreedy at udel.edu
Thu Sep 18 22:10:40 CEST 2008


Cliff Wells wrote:
> On Wed, 2008-09-17 at 23:54 -0400, Terry Reedy wrote:
>> 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's one other approach: have two types of functions: <function> and
> <function-with-lazy-args>.

This is what C and languages sort of have with functions and text 
macros.  Without a name convention (such as CPython uses in its 
codebase, with macros ALL_CAPS, I believe), one cannot tell, for 
instance, whether f(x) will or will not result in the passing of 'x' or 
eval(x).

It is what some Lisps used to have -- functions and special functions. 
Users had to memorized which args of which functions were normal and 
lazy.  There must have been some reason why that was superceded.

But to repeat: with Python's dynamic name binding, the compiler cannot 
in general tell whether the 'f' in 'f(x)' will be bound at runtime to a 
regular or special function, so as I said above, it would have to code 
for both possibilities.

>  Whenever Python encounters a declaration of
> a function with a lazy argument it creates the latter.  This would allow
> Python to know at runtime how to handle it.

This was already assumed in my original 'select between them at runtime 
according to an attribute of the function'.

 > The difference could be
> transparent to user code (although it might be unappealing to disguise
> such a difference).

Unless the argument expression has visible side-effects when evaluated.

I think there are also namespace issues that you have missed.  Consider

def f(`a,`b): # ` indicates lazy evaulation, after Lisp's 'quote
.....
blaf + f(a+b,c) -3
When f evaluates a bound to 'a+b', it has to *not* resolve 'b' to f's 
'b' but to the caller's 'b'.  As someone else said, the unevaluated code 
for 'a+b' is not enough.  A full enclosing function is needed.

tjr




More information about the Python-ideas mailing list