On Sun, May 24, 2020 at 10:53 PM David Mertz <mertz@gnosis.cx> wrote:
On Sun, May 24, 2020, 3:43 PM Guido van Rossum <guido@python.org> wrote:
I’ve never been able to remember whether (f@g)(x) means f(g(x)) or g(f(x)). That pretty much kills the idea for me.

Well, it means whichever one the designers decide it should mean. But obviously it's a thing to remember, and one that could sensibly go the other way.

On the other hand, when I showed an example using filter() a couple days ago, I had to try it to remember whether the predicate or the iterable came first. Lots of such decisions are pretty arbitrary.

But when you *read* a call to filter(), it's generally pretty obvious which argument is which, even if you don't remember the signature. You just need to see which one's callable or which one's iterable (few things are both). You can probably guess just from the variable names. If you read `f@g`, you can only guess if one of `f(g(x))` or `g(f(x))` is nonsense, which I think is typically less obvious. Taking the `len@str` example, `str(len(path))` is a sensible expression, it's just a terrible sort key, and having to think that far sucks for readability.

Also in the paths example, if you remember wrong and write the equivalent of `sorted(paths, key=lambda path: str(len(path)))`, you get a list in nonsense order which may be confusing to debug. If you get the order wrong in `filter()`, you should eventually get an error like `TypeError: 'list' object is not callable`.