On Jul 14, 2019, at 11:53, Anders Hovmöller <bo...@killingar.net> wrote: > > >>> On 14 Jul 2019, at 20:21, Andrew Barnert <abarn...@yahoo.com> wrote: >>> >> This does avoid the problem of needing new syntax, but it seems to have >> other problems. > > Well it does introduce new syntax, just one that is generally useful.
Right, sorry, I meant that it doesn’t need any new _symbols_, just a new use of an existing symbol (and in a way that’s unambiguous, both to parsers and humans). That’s obviously a big plus compared to using backticks. >> First, the function only gets the names, not live expressions that it can >> eval late, or in a modified environment, etc., so it only handles this case, >> not cases like df[year>1990]. > > I don't understand how it's not the full expression. It's the expression as a > string but it's still the full code. But this doesn’t in any way help with late eval. The caller has already evaluated the expression to pass the value of the keyword argument. The fact that you could ignore that value and re-do the eval doesn’t help if the eval would raise a NameError like the year>1990 case (or if it would do something expensive or dangerous). And it doesn’t help you eval against a modified version of the caller environment because you don’t have the caller environment. That’s what I mean by it not being a “live expression”. You don’t need that for the df[year>1990] case, but you do for some of the other examples. Consider just the minor change of replacing the constant 1990 with a local start: df[year>start]. The OP didn’t explain how this would actually work, but it seems pretty simple—e.g., just eval against a chainmap of __dict__ (to get the year column) over the bound locals (to get the start value). There’s no way to do that with your proposal. (Well, no way short of frame hacks that you can already do without your proposal.) Finally, while this is a less serious problem than the last two, the same string isn’t guaranteed to compile to the same AST in two different contexts. Consider how your proposal would play with libraries that insert token or AST processors. >> Second, the names show up as keyword argument names, not as values. Besides >> being a bit confusing to mix up names and values this way, it means >> everything has to be defined as def plot(**kwargs) and document its actual >> arguments some other way, and can’t annotate the parameter types, and if >> there are optional like the ones pyplot takes for point formatting, scale, >> etc., there’s no protection against them colliding with the names of the two >> fake-positional args. > > I think names being put with names isn't confusing ;) But yes, a system like > this would probably need other tweaks for API design but that's to be > expected. But they’re not being used as variable names, they’re being used as string values. That is the same confusion novices always run into that makes them ask “How do I create a local variable, for each file in a list, named after the filename?” The answer is that you don’t want to do that; you don’t want data in your variable names. But your proposal does exactly that. In the case of get(=url), that’s perfect, because you’re just saying the caller and callee both have the same value in a variable named “url”, which is exactly what you want to say. But in the case of plot(=lambda x:x*2, =lambda x:x**2), you’re saying that the callee has a variable named lambda x:x*2, which is not true. What the callee actually has is two unnamed positional arguments, each of which comes with an extra string argument buried as its name. (The fact that they’re positional, but passed as if they were keyword, accepted as if they were keyword, and then pulled out by iterating **kw in order is also confusing.) >>> This could work for any expression: >>> >>> foo(=lamda x: x*2) -> foo(**{'lamda x: x*2': lamda x: x*2}) >> >> Is this actually legal? The docs just say the contents of the ** mapping are >> treated as additional keyword arguments. CPython happens to check that they >> are strings but not check that those strings are valid keywords, but I don’t >> think the language definition actually says this is the intended behavior, >> it’s just an accident of the CPython implementation. So this might require >> at least defining that implementation behavior as the only correct one, and >> changing the docs to explain it. > > You are correct. I have checked that this is the behavior of CPython, pypy, > micropythob, iron python, and jython so shouldn't be a big burden. This might actually be a good change even on its own. The fact that the docs aren’t clear on what can go in a **kw is probably not a strength of the language definition but a flaw. If every implementation does the exact same thing (especially if it’s been that way unchanged in every implementation from 2.3 to 3.8), why not document that as the rule? >>> This feature is easy to implement and has broad applications. >> >> How is this implemented? Doesn’t the compiler have the same problem >> generating a string for the keyword out of an AST that the user code would >> have in the OP’s proposal? > > Sure. The lack of round tripping in the standard library AST is a problem but > in this case a simple AST dump is most likely fine even if it loses the users > specific formatting. It’s not just about a lack of round tripping in the standard library AST, it’s about a lack of round tripping in the implementation of the CPython, PyPy, etc. compilers. If the compilers don’t have access to that information internally, they can’t put it in the output. And I think it would be pretty confusing if spam(=eggs+cheese) gave you an argument named “eggs + cheese” instead of “eggs+cheese”. And it would be annoying if you were using it to define labels on a displayed graph—you keep trying to tweak the code to change how the label is written and it doesn’t do what you tell it to do. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XPGGEHWJIC4A25E2SAILNFNSMWZ4Z25O/ Code of Conduct: http://python.org/psf/codeofconduct/