> On 14 Jul 2019, at 22:46, Andrew Barnert <[email protected]> wrote:
>
>>> 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).
Ah. Now I'm with you. Yes this is different but it also seems strange that we
wouldn't just use a lambda or a function for that. That's exactly why they
exist.
> 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.
Hmm, well I've never seen one of those outside toy programs but I'll concede
the point.
> 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.
I disagree. The callee has a thing called that, it just isn't a variable but a
local expression. And in any kwargs have never meant that the caller has a
variable by the name of the callee argument so why would it here?
> (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.)
What is positional? Everything here is keyword. We must be talking past each
other. My proposal is just a different short syntax for keyword arguments at
the call site.
>
>>>> 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?
Agreed! If you don't follow this you are de facto a broken python
implementation even if the spec allows it.
>
>>>> 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.
Agreed. But there must be a way to explicitly specify the label anyway so I
don't think this is a deal breaker.
/ Anders
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/F7QFBVGJB2LGDKMQYSVOLR5RC46TNC7H/
Code of Conduct: http://python.org/psf/codeofconduct/