[Python-ideas] Alternative to PEP 532: delayed evaluation of expressions

Brendan Barnwell brenbarn at brenbarn.net
Mon Nov 7 01:13:18 EST 2016


On 2016-11-06 21:46, Steven D'Aprano wrote:
> I sometimes think that such unevaluated expressions (which I usually
> call "thunks") would be cool to have. But in more realistic moments I
> think that they're a solution looking for a problem to solve.
>
> If your PEP suggests a problem that they will solve, I'm interested.
>
> But note that we already have two ways of generating thunk-like objects:
> functions and compiled byte-code.
>
> thunk = lambda: a + b - c
> thunk()
>
> thunk = compile('a + b - c', '', 'single')
> eval(thunk)
>
> Both are very heavyweight: the overhead of function call syntax is
> significant, and the keyword "lambda" is a lot of typing just to delay
> evaluation of an expression. compile(...) is even worse.

	I sometimes want these too.  But note that both the solutions you 
propose are quite a ways from a true "unevaluated expression".

	The big problem with an ordinary lambda (or def) is that you cannot 
explicitly control where it will decide to look for its free variables. 
  If it uses a local variable from an enclosing namespace, it will 
always look for it in that namespace, so you can't "patch in" a value by 
setting a global variable.  If it uses a variable that isn't local to 
any enclosing namespace, it will always look for it in the global 
namespace, so you can't patch in a value by setting a local variable in 
the context where you're calling the function.

	You can get around this in a def by, for instance, using global to mark 
all variables global, and then using eval to pass in a custom global 
namespace.  But that is a lot of boilerplate.  What I want (when I want 
this) is a way to create a function that will allow the injection of 
values for *any* variables, regardless of whether the function 
originally thought they were local, nonlocal (i.e., local to some 
enclosing scope) or global.  The way it is now, the status of a 
function's variables is inextricably linked to the syntactic context 
where it was defined.  This is a good thing most of the time, but it's 
not what you want if you want to define an expression that should later 
be evaluated in some other context.

	I consider the compile-based solution a nonstarter, because it puts the 
code in a string.  With the code in a string, you are blocked from using 
syntax highlighting or any other handy editor features.

-- 
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."
    --author unknown


More information about the Python-ideas mailing list