On 14 November 2016 at 19:01, Ryan Fox <r...@rcfox.ca> wrote: > (Hi, I'm a first-time poster. I was inspired by Raymond Hettinger's keynote > at PyCon CA to look at new PEPs and comment on them. Hopefully, I'm not > committing any faux-pas in my post!) > > 1) I don't think this proposal sufficiently handles falsy values. > > What is the expected value of x in the following? > > x = exists(0) else 1 > > Since the PEP specifically states that exists() is to check that the input > is not None, as a user, I would expect x == 0. However, from my > interpretation, it appears that the value 0 would still be directly > evaluated for truthiness and we would get x == 1.
No, the conditional branching would be based on exists.__bool__ (or, in the current working draft, is_not_none.__bool__), and that would be "0 is not None", which would be True and hence short-circuit. > I don't fully get what the purpose of __then__ and __else__ are meant to be, > but it seems like instead of this: > > type(_lhs).__then__(_lhs) if _lhs else type(_lhs).__else__(_lhs, RHS) > > you would want: > > LHS if type(_lhs).__then__(_lhs) else RHS `__then__` is responsible for *unwrapping* the original value from the circuit breaker when it short-circuits: it's what allows the overall expression to return "0", even though the truth check is done based on "0 is not None". > Where __then__ returns a simple True/False result. (Maybe the name __then__ > doesn't make sense in that case.) We already have a method for that: __bool__. However, it has exactly the problem you describe, which is why "0 or expr" will always short-circuit, and why "(0 is not None) or expr" will return "True". > 2) My initial reaction was that `else` doesn't belong in an expression, but > I guess there's already precedent for that. (I actually wasn't aware of the > `x if y else z` expression until I read this PEP!) > > I'm already not a fan of the overloading of else in the cases of for/else > and try/else. (Are there other uses? It's a hard thing to search on > Google...) Now, we're going to have `else`s that aren't anchored to other > statements. You've always known that an `else` belonged to the preceding > if/for/try at the same level of indentation. (Or in the same expression.) > Is there a chance of a missing colon silently changing the meaning of code? > > if foo(): > a = 1 > else > bar() > > (Probably not...) No, due to Python's line continuation rules - you'd also need parentheses or a backslash to avoid getting a SyntaxError on the unfinished line. It does create amibiguities around conditional expressions though, hence why that comes up as one of the main pragmatic concerns with the idea. > Are two missing spaces too outrageous? > > x = yiffoo() else bar() > > I'm not 100% sure, but I think that a current parser would see that as a > syntax error very early, as opposed to having to wait for it to try to find > 'yiffoo' at run-time. That style of error is already possible with the other keyword based operators: x = notfoo() y = xorfoo() z = yandfoo() As you not, the main defense is that this will usually be a name error, picked up either at runtime or by a static code analyser. > 3) Towards the end, you propose some very Perl-like syntax: > > print(some_expensive_query()) if verbosity > 2 > > This seems completely unrelated to the rest of the PEP, and will likely > invite people to propose an `unless` operator if implemented. (Followed by > an `until` statement.) :) > > While it does read more naturally like English, it seems superfluous in a > programming language. De Morgan's laws [1] mean that 'and' and 'or' are technically redundant with each other, as given 'not', you can always express one in terms of the other: X and Y --> not ((not X) or (not Y)) X or Y --> not ((not X) and (not Y)) However, writing out the laws like that also makes it clear why they're not redundant in practice: the inverted forms involve double-negatives that make them incredibly hard to read. Those rules impact this PEP by way of the fact that in "LHS if COND else RHS", the "if" and "else" are actually in the same logical relation to each other as "and" and "or" are in "COND and LHS or RHS". Accordingly, if "LHS if COND else RHS" were to be reformulated as a compound instruction built from two binary instructions (akin to the way comparison chaining works) as considered in the "Risks and Concerns" section about the language level inconsistencies that the current draft introduces, then we'd expect De Morgan's laws to hold there as well: Y if X --> not ((not X) else (not Y)) X else Y --> not ((not Y) if (not X)) It hadn't occurred to me to include that observation in the PEP while updating it to switch to that base design, but it really should be there as an additional invariant that well-behaved symmetric circuit breakers should adhere to. [1] https://en.wikipedia.org/wiki/De_Morgan%27s_laws > 4) The proposal shows how it fixes some common pain points: > > value = missing(obj) else obj.field.of.interest > value = missing(obj) else obj["field"]["of"]["interest"] > > But it doesn't address very similar ones: > > missing(obj) else missing(obj.field) else missing(obj.field.of) else > obj.field.of.interest > obj.get('field', {}).get('of', {}).get('interest') > > (The first example shows how it would be handled with the PEP in its current > state.) > > Maybe these are too far out of scope, I'm not sure. They feel very similar > to me though. The current draft already indicates it doesn't aim to compete with the "?." or "?[]" proposals in PEP 505 (which handle these two cases), and the next draft drops the competition with "??" as well. That way, the proposed circuit breakers for the PEP 505 cases can just be "operator.is_none" and "operator.is_not_none". > I hope these are useful comments and not too nit-picky. They were very helpful, and picked up a key technical point that I'd missed in the revised proposal I'm currently working on. I think I also need to restore a diagram that Mark E. Haase drew for an earlier draft of the PEP that may make it easier for folks to visualise the related control flow. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/