On Wed, Aug 22, 2018 at 06:28:45PM -0500, Abe Dillon wrote: [Steve -- that's me] > > But whatever it is, do you still think it is obvious that people > > will recognise "None" to mean a function without having to backtrack? > > > It's not clear what you mean by backtracking at this point.
Yes, I accept that's not clear. Sorry. What I mean is that moment of having to reinterpret what you're reading. I start to read code, see that its assigning None to a parameter, and then a moment later have to re-interpret what we just read: None is not the argument, but the body of the function which is the argument. In linguistics that sort of thing is called a "garden path sentence" and research demonstrates readers take longer to comprehend them than sentences which don't require backtracking (re-interpretation). https://en.wikipedia.org/wiki/Garden-path_sentence Sometimes that's a good thing, if you're making a joke. But in general, they're not great for readability. Since your argument hinges on readability, that's a problem. > cleanup=None > with() requires no more backtracking than any other compound expression. > cleanup=children.oldest().room doesn't tell you what kind of object is > being assigned to cleanup. Is it a function? Who knows? Even if you know > what > 'children' is and what the 'oldest' method returns, you still don't know > what's being assigned to cleanup without reading the entire expression. But at no point in reading "children.oldest().room" do you have to go backwards and re-intepret what you thought you saw. Even if the expression involves right-associative operators: children ** oldest ** room the worst that you have to do is defer thinking about children (push it onto the stack of short-term memory) until after you've thought about oldest**room. Now human memory has a very shallow stack. We struggle to hold more than approximately "seven plus or minus two" items in memory at a time. And of course people often forget that ** is right-associative (I know I do). But syntactically, there's no mental backtracking required. I'm not claiming that your suggested syntax is impossible in a LL(1) grammar like Python. I don't know. But I'm responding to your earlier assertion that it ought to always be obvious in context that you are looking at the body of a function, before you see the "with" keyword. As evidence for this assertion, you give examples where it is obvious: sort(sequence, by=card.suit with card) Sure, any English speaker familiar with the English idiom "sort by ..." can probably guess the semantics. That's great. But its not representative. We don't always have the luxury of expressions which read like English phrases: threading.Thread(target=None ... looks like the target is None, not a function, and we don't realise its not until we keep reading and learn at the very end of the expression that everything we saw before that point was part of the function body. It's great for English speakers that "sort by" appears in our code, but have a thought for those to whom it might as well be "pteg xb". Python is not just a language for English speakers, and if we're going to claim a readability advantage, we ought to at least acknowledge that not everyone will have that advantage, and not exaggerate the magnitude of that advantage by using words like "almost always". > There has never been a guarantee that expressions evaluate left to right > simply by virtue of the fact that an order of operations exists. That's fine, because I never said they did. It would be pretty foolish of me if I did, given that exponentiation is right-associative, and that we have comprehensions and ternary if expressions. > > sm = difflib.SequenceMatcher(isjunk=x == ' ' with x, ...) > > The expression x==' ' doesn't look like a function to me. > > > You don't think that perhaps that's because it's brand new syntax? > x=='' doesn't look like a function because it's not a function. I know that. But you stated: "I was trying to say that the context almost always gives away that the reader should expect a function." The difflib example is a real, not made up, example that goes against that. The context "isjunk" sounds like it might be a flag, not a function, and the code x==' ' supports that interpretation right up to the moment you read "with x" part, at which point you have to re-interpret what you've been reading. > You could play the same game with literally any compound expression: > > >>> func = ", ".join > > ", " doesn't look like a function to me! Indeed. I don't deny that there are expressions where if you truncate at a certain point, the code up to that point looks like a valid (sub-) expression of a different type: spam ∆ eggs If you truncate just before the ∆ you get a valid subexpression "spam" which may not be the same as the expression "spam ∆ eggs". But there aren't many places in Python where after truncating just before ∆, you interpret "spam" one way, but if you truncate after the ∆, you intepret "spam" a different way. Normally spam is spam no matter what follows it. In your earlier example ", " is a string, regardless of whether you have read up to the dot or not. Of course we could do this (LL(1) parser permitting) but the point I'm making is that this isn't a small change, and I don't think it will have the benefit you believe it will. The contrary: I think it will hurt readability, not help it. I think the benefit of moving the body of the function to the front is less than you think, and the cost of moving the syntax which distinguishes it as a function to the end greater than you think. I don't have objective evidence for these opinions, but I've tried as best as I am able to give the reasons why I believe this, and not just make it an assertion. > If you honestly don't understand my position at all. [...] > then I guess I've never met anyone quite like you. I'm a unique and special snowflake. https://i.imgur.com/W3ljlBg.jpg > I don't > know how to communicate my point of view any better than I already have. I understand your position. I just disagree with it. > [Steven D'Aprano] > > You are judging that from the perspective of someone whose native > > language makes it easy to say "sorted by foo" (for some value of foo). > > This argument is such a tiring distraction. Please stop. If it's all just > random symbols to some non-english speaker, then > It doesn't matter either way to them. When you are claiming an advantage, if that advantage doesn't actually apply, then its not an advantage, is it? I'm not going to stop using a valid argument just because you don't like it. > [Steven D'Aprano] > > We shouldn't judge syntax proposals just on the cases that are carefully > > chosen to showcase them at their best. Especially not trivial cases. > > We can judge it by examining cases where it might be problematic, but > there's no way to keep people from abusing > coding constructs to produce unreadable code, so just throwing out random > chunks of code like > > a.b[c:d]-e**f(g, h=i) + {j & k, l*(m-n(o,p))} with e, k > > then saying "looks bad to me" offers no insight into the pros and cons of > the proposal. Good thing I didn't do anything like that. Abe, you are attacking a strawman. I didn't give made-up deliberately awful code. I took existing code from the standard library, and translated it to your proposed syntax. These "random chunks of code" are a non-issue. I never suggested examples like that, and I haven't seen anyone else do so either. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/