Thanks for reply, I can see most of what you have written.
> But "encourages one-liners" is generally considered an anti-pattern in > Python. Let's see why, Here I am a bit confused, how is this the case in the language containing list comprehensions? I would understand if it was swapped with “bad quality & unreadable 1-liners”. Also, I would rephrase “encourage 1-liners” to “promote readable and expressive structures that are balanced in their brevity versus complexity”. I am not encouraging 1-liners, I am more arguing that certain things in relation to average complexity should take no more than 1-line. I am always very happy to write multiple lines. E.g. I often use loops instead of list comprehensions: l = list() for i in range(10): l.append(func(i)) These 3 lines justify themselves. A reasonable amount of logic and complexity is contained in them. While I could not say the same about: if a < 1: c = a else: c = default For what it does, it feels it should’t take more than half the space that the “for” loop above is taking. Btw, here I would probably prefer: def clamp_int(n: int, lo: int, hi: int): if lo > hi: raise ValueError(f'{lo=} > {hi=}') return lo <= n <= hi ? n : (n > hi ? hi : lo) I emphasize readability more in high-level code, APIs, non-numeric routines and similar. E.g. In numpy code I sacrifice a lot of that “english” readability for aesthetics and brevity, as it is closer to scientific space, where everything is pretty much named with 1-letter + glossary. I think the place I am coming from is more about balance than brevity. In other words, outliers in multi-dimensional spacecan feel awkward to me. Obviously, my dimensions might not be the same as someone else's. > On 18 Jul 2023, at 16:38, Stephen J. Turnbull > <turnbull.stephen...@u.tsukuba.ac.jp> wrote: > > Dom Grigonis writes: > >> I came to this, because people seem to want one-liners for certain >> things and what I came up with is that maybe more concise if-else >> expression could help. > > But "encourages one-liners" is generally considered an anti-pattern in > Python. Let's see why, > >> # Fairly reasonable case. > >> def foo(a: bool, c: float, d: float) >> val = a ? (c ? c : d) : (d ? d : c) >> return val > > What's not so great here? > > 1. The argument names are not going to be single characters, unless > you intentionally name that way for the sake of one-line-ism. > That severely detracts from your claim of readability. The > one-liner is arguably[1] more readable than the Python version, > but you've definitely made the whole function less readable. > > 2. Comparing floats, even against zero, is a bad idea. So I would > wrap them in math.isclose: > > val = a ? (not isclose(c, 0) ? c : d) : (not isclose(d, 0) ? d : c) > > Pretty long, not that easy to read. Of course if you had > intelligible variable names it would be worse. > > The point is *not* to give you a hard time about comparing floats > for equality, we've all done that. It's that in even in this > example, done safely you have more complex expressions than just > variable references. In general you will have function calls > adding parentheses -- and thus confusion. Perhaps there will be > lists or tuples involved. You can precompute them and assign > them to short name variables, but then you lose the one-liner-ness. > > 3. OK, how about ints then? Yes, that would work, but how frequently > are you going to be comparing against 0? Here's a more realistic > case, with readable short argument names: > > def clamp_int(n: int, lo: int, hi: int): > # I wouldn't elide this test because if lo > hi you get a > # plausible but necessarily erroneous value > if lo > hi: > raise ValueError(f'lo = {lo} > {hi} = hi') > val = n < lo ? lo : (n > hi ? hi : n) > return val > > Agreed, the expression using Python's syntax would be worse, but I > think this is much more readable: > > def clamp_int(n: int, lo: int, hi: int): > if lo > hi: > raise ValueError(f'lo = {lo} > {hi} = hi') > if n < lo: > val = lo > elif n > hi: > val = hi > else: > val = n > return val > > and it would be more readable yet if you got rid of the > assignments and just returned the value as soon as you see it: > > def clamp_int(n: int, lo: int, hi: int): > if lo > hi: > raise ValueError(f'lo = {lo} > {hi} = hi') > # Hi, David! Default first!! > if lo <= n <= hi: # Yes, Virginia, valid Python! > return n > elif n > hi: > return hi > else: > return lo > > (Yes, I know that some folks argue that suites should have one > entry point and one exit point, but I don't think it's a problem > here because of the extreme symmetry and simplicity of the > conditional. IMHO YMMV of course) > >> I dare you to do a 1-liner with current if-else. > > I do use ternary expressions occasionally, but almost never nested. > Writing one-liners is never a goal for me, in part because my old eyes > can't take in more than 35-40 characters in a gulp. > >> So maybe, just maybe, making already existing expression more >> readable can also be a valid suggestion? > > We *won't do that*, because of backward compatibility. The syntax of > an exist expression cannot change without invalidating a lot of > existing code. That's one reason why the bar to new syntax is so > high, and it took so long to get the ternary expression: you really > want to get it right. That's why Python (like C!) prefers to add to > the stdlib rather than the language. > > Now, you can add a new one that does the same thing, and that's been > done. IIRC it took a while to get +=, and C-like ++/-- increment > operators have been requested over and over again. AFAIK the async > syntaxes do nothing that can't be done with generators, but they make > it a lot easier to do it right in the most common cases. > >> As I said, in my opinion it would solve many existing queries and >> requests, just because certain things would become very pleasant >> and obvious how to do in simple one-liners. > > One-liners are almost by definition less readable. Even in math > papers we break equations into a series of definitions and then build > up the final equation from there. As M. Spivak put it in *Calculus on > Manifolds*, > > Stokes' theorem shares three important attributes with many fully > evolved major theorems: > 1. It is trivial. > 2. It is trivial because the terms appearing in it have been > properly defined. > 3. It has significant consequences. > > When I have the time and knowledge, I aspire to programming that > way. :-) YMMV > >> Simpler and more logically convenient if-else combined with other >> elegant python expressions would potentially fill that gap. > > I guess. It's certainly true that Python pre-walrus operator had no > good solution to the "loop and a half" problem. But I've been > programming long enough it's hard to get myself to use the walrus > operator in the "assign and return" fashion that C's assignment > operator so frequently is. > >> From where I currently stand it just seems fairly happy middle >> solution between: very concise narrow functionality requests and >> very verbose ways of how they need to be done at the moment. > > But the functionality you request is extremely narrow in a different > sense. At least the way people who develop Python (and GNU Mailman, > where I program Python in anger, as they say) taught me, very > frequently the most concise expression is not the most readable, and > "readability counts". So as above I would likely exand these > expressions into statement syntax in many cases anyway, despite having > a more concise syntax. > >> I fully appreciate how likely what I am proposing is going to be >> even considered. But I really think it should be. > > I think you will find almost noone in Python development who would > agree that it *should* be. Even if you 100% discount the "20 years > late" objection that stops it before it gest started. > > A lot of the arguments you make would be good arguments, or would have > the form of good arguments, for other features. Your "sense" of > language development is good, IMO. But if you want to contribute to > Python development you need to choose the features to support more in > line with conventional wisdom. For example, Chris A's PEP on default > argument processing (is that the PEP 671 mentioned earlier?) would > resolve what many consider to be a wart, and it hasn't been rejected, > just postponed. Or you could choose one that is not merely > duplicating existing functionality with syntax ore to your taste. > > Steve >
_______________________________________________ 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/WH6YBYWXDUQK53IIP4CFOF6PQFSFMH35/ Code of Conduct: http://python.org/psf/codeofconduct/