[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