On Sunday, June 23, 2019, 10:13:07 PM PDT, Chris Angelico <ros...@gmail.com> wrote: > The biggest problem with this proposal is the way that, being a > syntactic construct, it's going to be non-composable.
> # Oops, syntax error > with (some_expr as q, > some_other_expr as w):> pass I don't understand. Are you suggesting that some_expr could be something like "2 if cond else pass", so if not cond, this is supposed to be equivalent to "with ( as q, some_other_expr as w):", which is a SyntaxError (at runtime)? If so, that's the same problem as with most other syntactic locations where an expression can go, like the assignment example I gave earlier. Anyway, I think we need to make this more concrete. Python semantics aren't defined in terms of syntax rewriting rules, so trying to discuss this suggestion as if it were a syntax rewriting rule is only going to lead to confusion. If the restrictions on pass are to be syntactic, they're in the grammar, and "x = 2 if cond else pass" is a SyntaxError, at compile time, because it's not valid syntax for an assignment statement. If not, then they're defined in the semantics attached to the grammar; "x = 2 if cond else pass" is a valid assignment statement, whether cond is true or false, and some node in that statement's tree is going to tell us what it means—in this case, that it raises some error (let's all it NoValueError) at runtime if cond is false. Either way, I think you want to start with a restricted set of places pass can be used or propagated. If it's possible (and I'm pretty sure it is), it's much easier to just define the changed behavior of a handful of nodes we care about, than to grub through the entire language looking at how each construct would handle it. (Plus, you'd definitely want to be conservative here—adding pass-handling to return statement or or expressions in a later version breaks nothing, but removing it breaks working code.) So, pass has to change from a statement to an expression. And then you need to define the semantics of a few things: the new pass expression, the handful of places where you want pass is meaningful as a final value (I believe that's just 6.2.4 displays, 6.3.4 calls, 6.14 expression lists, and 7.1 expression statements), and the handful of places where pass can propagate up (that could be just 6,12 conditionals). For example, in 6.14, you change the first paragraph to say "… number of expressions in the list **that do not evaluate to pass**." In 6.12, you add "… y is evaluated and its value is returned. **In this case, if y evaluates to pass, the conditional evaluates to pass.**" If it's not syntactic, then you're almost done, you just need to add a new blanket rule that says that when an expression evaluates to pass in all cases except as specified otherwise, then a NoValueError is raised. So, "x = 1, 2 if spam else pass, 3" evaluates to (1, 3) when not spam because the semantics for expression list (and conditional expression) tell us what happen; "x = 2 if spam else pass" raises a NoValueError because assignment and expression don't specify otherwise. If it is syntactic, then you don't need that all-other-cases bit, and don't need the exception at all. Instead, you need to change the grammar in 6.12 and friends to use a new node called pass_expression instead of expression, and that node can include pass_conditional_expression instead of conditional_expression, and… propagate that forking as far into the grammar as you have to. Nw, "x = 2 if spam else pass" is a SyntaxError because "2 if spam else pass" is not an expression, but "x = 1, 2 if spam else pass, 3" is valid syntax because "2 if spam else pass" is a valid pass_expression, and therefore a valid starred_item, and therefore the whole list is a valid starred_list (which, at runtime, will be either (1, 3) or (1, 2, 3)), and therefore the statement is valid. I'm not sure how many nodes are in that "as far into the grammar as you have to", but each change is trivial; it's just a bit tedious to walk the whole graph, and since I'm -1 on the proposal, I'm not going to do it.
_______________________________________________ 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/IUDJE4G6XWODP7TPOKZOKJUHIDTMCU2X/ Code of Conduct: http://python.org/psf/codeofconduct/