On 11/23/2020 4:49 PM, David Mertz wrote:
On Mon, Nov 23, 2020, 4:32 PM Eric V. Smith 

I just commented on Steve's post over on Discourse. The problem with this is that the called function (m.case, here) needs to have access to the caller's namespace in order to resolve the expressions, such as StringNode and PairNone. This is one of the reasons f-strings weren't implemented as a function, and is also the source of many headaches with string type annotations.

Is this really true though? Yes, it would require magic of the sort zero-argument `super()` does. But can't the Matcher constructor capture the locals one step up the stack on instance creation? That's largely why my strawman version is slightly different from Steve's strawman.

Beyond the issue of stack access being frowned on, there are some practical problems. One that's given in PEP 498 is closures accessing variables that aren't otherwise referenced:

>>> def outer(x):
...     def inner():
...         return 'x={x}'.format_map(locals())
...     return inner
>>> outer(42)()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in inner
KeyError: 'x'

Whereas an f-string in that scenario does work:

>>> def outer(x):
...     def inner():
...         return f'x={x}'
...     return inner
>>> outer(42)()

I'd put the question this way: assuming Matcher can be written (with a bit of stack magic), and assuming that the strings inside m.case() calls are exactly the same mini-languague PEP 634 proposes, would you want a syntax change?

No, I wouldn't!

Something that gets brought up every now and again is: what if there were a way to pass an AST to a function, such that it received the AST instead of the evaluated value for a parameter. Let's say that backticks (`) meant "compute the AST of the enclosed expression", and that was passed it to the function. (I always choose backticks for this example because we all know it isn't going to happen.)

Then you write your original example using backticks instead of quotes, and m.case would get an AST it could inspect. It would probably still need some help in evaluating the AST nodes in the caller's context, but at least it would be theoretically possible to do so with the compiler's assistance.

Another option would be the function itself saying "give me an AST instead of evaluating a particular parameter". But that's all but impossible, since the compiler couldn't look at the called function to know it wants to do that.

I think we're in python-ideas land now.


That's not rhetorical, I'm of mixed feeling myself.

Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ZQBAYYR5KJFJVXVYQQ3TIS5JLJZDM3K3/
Code of Conduct: http://python.org/psf/codeofconduct/