On Sat, 5 Mar 2022 at 12:43, Chris Angelico <rosuav@gmail.com> wrote:
The throwaway function is a *terrible* idea for a lot of situations, because it puts the condition completely out-of-line. You have to go dig elsewhere to find out the meaning of the filter. A lambda function can work, but is about as clunky as the genexp. Using filter() is only non-clunky in the specific situation where a function already exists to do the filtration, and in my personal experience, that's been quite rare.
*shrug* I'm not sure I'd agree with you that throwaway functions are quite as terrible as you claim, but we're into the area of personal preference, so I'm not going to debate that one. But equally "let's have new syntax because some people find the current options unattractive" is a difficult argument to sell. So I'm still inclined to ask for something more objective.
If we had "placeholder" expressions (see, for example https://pypi.org/project/placeholder/) so we could do things like
from placeholder import _ for thing in filter(_%3==0, the_list): ...
would that be sufficiently "non-clunky"?
That is something I could get behind. I don't like the underscore, since that usually means "meaningless", and would have to be carefully managed to avoid shadowing; but that is definitely a possibility.
I've not used the library extensively, and I'd encourage you to read the docs if you want details, but you can of course do "from placeholder import _ as X" (or whatever placeholder you prefer).
Does it work if you need to use the underscore twice? For instance, what if you want to find long-running jobs, where "_.end - _.start > 30" ?
Yes. Again, check the docs for all the details, but this does work.
(This also still has the performance cost of filter and a lambda function, which is a lot more than just having a bit of extra code as part of the loop. But that's less significant.)
From the library docs, "Every effort is made to optimize the placeholder instance. It's 20-40x faster than similar libraries on PyPI" and "Performance should generally be comparable to inlined expressions, and faster than lambda". I've not done measurements myself, but I did do some investigation in the past, and the claims seem realistic.
There are many ways of achieving this sort of result. Clearly, from the fact that this request comes up repeatedly, there's *something* unsatisfying about all of them, but I'm not entirely clear what particular problem is uniquely solved by new "for x in collection if condition" syntax, and not by any of the other possibilities?
They are all clunky except in very specific circumstances, like "iterate over the non-empty elements" or something. They don't generalize well.
I'm not sure how a for-if statement generalises any better than for ...: if not (condition): break So "doesn't generalize well" isn't the whole story here, I suspect.
Personally, I don't mind having the if on a separate line, I find the generator expression tolerable but a bit verbose, and I'm glad "filter" and the placeholder library exist in case I need them, but I've never really found the existing options sufficiently annoying that I've wanted a for...if statement.
And clearly a number of other people DO mind having it on a separate line, because it's putting code in the body that belongs in the header.
I don't disagree, and if that's the argument, then I'm fine with that.
However, as I found out by writing PEP 671, there are enough people who focus on the concrete that it's never going to happen. All you have to do is keep on arguing against straw-men and eventually people get weary of arguing the same unanswered arguments again and again.
If someone were to implement this feature, I wouldn't object. In fact, I'd probably use it (not often, maybe, but I wouldn't actively avoid it). For comparison, though, I've yet to use an assignment expression, so don't put too much weight on "Paul would use it" as a measure of acceptability ;-) I think the problem here is that getting enthusiastic community support is always going to be hard, and as Python's user base gets bigger, any group of supporters looks smaller and smaller in comparison. "Everyone likes this, let's implement it" is probably the wrong way of getting language changes through these days, TBH (if indeed it ever was the right way...) But the PEP process is perceived (and presented) as a process of getting consensus, even though it isn't, really. Paul