[Python-ideas] Backtick expression: similar to a shorter lambda syntax

Steven D'Aprano steve at pearwood.info
Mon Jan 21 17:38:00 EST 2019


On Mon, Jan 21, 2019 at 05:56:17PM +1100, Steven D'Aprano wrote:
[...]

> > And a few more examples for clarity.
> > 
> > def example():
> > locals()['a'] = 1
> > expr = `a+1`
> > return expr() # error: one variable is required
> 
> Still not clear to me. It might help if you showed expected input and 
> output, rather than expecting us to guess.

My comment there is excessively terse and I should explain, my 
apologies.

Assigning to the ``locals()`` dictionary is not guaranteed to create or 
modify the equivalent local variable. Inside a function, 
``locals()['a'] = 1`` is NOT the same as ``a = 1``.

In CPython, such assignments don't work, although many people don't 
realise that. In other implementations, they might. So I'm not sure if 
this is meant to just be a fancy way of assigning to ``a``, or a fancy 
way of NOT assigning to ``a``, which gives me two possible 
interpretations of that example depending on whether or not James is 
aware that writing to locals() may or may not create a local variable.

    # Backtick expressions don't resolve locals.
    def example():
        a = 1
        expr = `a+1`
        return expr() # error: one variable is required

The alternative is a bit harder to guess what it does, since we don't 
know whether there is or isn't a global variable ``a``. But given that 
apparently we are required to pass ``a`` as an argument to the 
expression object, I guess that the second interpretation is:

    # Backtick expressions don't look for globals.
    a = 1  # or not, the behavious doesn't change (or does it?)
    def example():
        expr = `a+1`
        return expr() # error: one variable is required


Personally, *either* behaviour seems so awful to me that I can hardly 
credit that James Lu intends either. The second one means that 
expression objects can't call builtin or global level functions, unless 
you pass them in as arguments:

    obj = `len([]) + 1`
    obj()  # Fails with NameError
    obj(len=len)  # Returns 1

which seems ludicrous. But that appears to be the consequence of 
requiring variables that aren't in the local scope to be passed as 
arguments.

Since I cannot believe that James actually intends either of these 
behaviours, I can only repeat my request for clarification. What is this 
example supposed to show?


-- 
Steve


More information about the Python-ideas mailing list