News for hackers. Stuff that matters.
Re:Functools – The Power of Higher-Order Functions in Python by roenxi on Friday July 09, 2021 @03:37AM (#27781331)
> ...like groupBy(fn), sortBy(fn), countBy(fn), collate...

What leaps out at me is that these 3 functions are all straight out of relational algebra style worldview.

Python the language doesn't support relational algebra as a first class concept. The reason it feels like IKEA self assembly is probably because you are implicitly implementing a data model that isn't how Python thinks about collections.

Re:Functools – The Power of Higher-Order Functions in Python by quietbritishjim on Friday July 09, 2021 @04:18AM (#27781531)
Exactly. Pythonic versions:

    groupBy(fn): {fn(x): x for x in foo}
    sortBy(fn): sorted(foo, key=fn)
    countBy(fn): Counter(fn(x) for x in foo)
    flatten: [x for y in foo for x in y]
    filter(fn): [x for x in foo if fn(x)]
All the "for x in blah" can seem like a lot of boilerplate for a non-Pythonista, but actually it becomes subconscious once you're used to it and actually helps you feel the structure (a bit like indentation isn't necessary in C but it still helps you to see it).

For compound operations (e.g. merge two lists, filter and flatten), I find the code to be a lot more easier to "feel" than if you'd combined several functional style functions, where you have to read the function names instead of just seeing the structure.

Re:Functools – The Power of Higher-Order Functions in Python by cwilkes on Friday July 09, 2021 @04:39AM (#27781639)
That groupBy doesn’t look like it does what you want to do.

For example if

“def fn(i): return i//2”

You probably want to get an output like {0: [0,1]} but you’ll only get a scalar for the value (1) and it will be the last one evaluated.

It would be nice if there was a way to do this on one line but you’ll have to do

ret=collections.defaultdict(list) For i In foo: ret[fn(i)].append(i) Return ret

I suppose it isn’t that bad as it will be in the groupBy method.

Or you could add it to a method on a list. I think that’s easier to do with Rust.

Re:Functools – The Power of Higher-Order Functions in Python by quietbritishjim on Friday July 09, 2021 @06:45AM (#27782338)
Hmm, you're right... that one is actually quite hard to do in a Python-ish way. There is a one liner, just for the record, but it's absolutely horrific code because it redundantly re-evaluates the same conditions over and over:

    g = {fn(x): [y for y in foo if f(y)==f(x)] for x in foo}
As you said, you'd have to use a for loop. I think sometimes people are unnecessarily afraid of for loops in Python (not everything has to fit on one line!) but this is a case it's a pity to take up so many lines. Or, back to square one, probably this is a case it's best just to use itertools groupby (after a sort) after all.
Re:Functools – The Power of Higher-Order Functions in Python by matsemann on Friday July 09, 2021 @05:52AM (#27782060)
> All the "for x in blah" can seem like a lot of boilerplate for a non-Pythonista

It's not the boilerplate that's the problem, it's that using the same construct for everything doesn't convey its intention.

If I see a chain of filter, map, group etc., I instantly know what each part does. I know that filter does a filtering, and then I can look at the function passed to it do know how exactly it's filtering. If I see a list comprehension, I have to first understand if it's filtering or mapping or whatever (or even all at once), before I can grok it.

Re:Functools – The Power of Higher-Order Functions in Python by unishark on Friday July 09, 2021 @04:37AM (#27781625)
Speaking of the list and set comprehensions, they also mimic formal mathematical notation e.g. {f(x) | x>0, x in reals} or whatever
Re:Functools – The Power of Higher-Order Functions in Python by formerly_proven on Friday July 09, 2021 @06:47AM (#27782349)

    filter(fn): [x for x in foo if fn(x)]
Python has filter(predicate, iterable) -> iterable built in.
Re:Functools – The Power of Higher-Order Functions in Python by quietbritishjim on Friday July 09, 2021 @06:56AM (#27782392)
Absolutely but it's not "Pythonic". Guido said:

> About 12 years ago, Python aquired lambda, reduce(), filter() and map(), courtesy of (I believe) a Lisp hacker who missed them and submitted working patches. But, despite of the PR value, I think these features should be cut from Python 3000.

("Python 3000" was the code name for Python 3.) He eventually stepped back from this hard line view but it remains a fact that it's a bit of a historical accident that it's present at all.

[1] https://www.artima.com/weblogs/viewpost.jsp?thread=98196

Re:Functools – The Power of Higher-Order Functions in Python by Zababa on Friday July 09, 2021 @09:32AM (#27783479)
The thing is, filter is present in almost all languages now while list comprehensions are in Python, Julia and Haskell. Maybe it's not "pythonic", but Python doesn't exist in a vacuum and is influenced by other languages, as proven with the optional typing and the pattern matching. Maybe it's time to review the definition of pythonic?
Re:Functools – The Power of Higher-Order Functions in Python by globular-toast on Friday July 09, 2021 @05:40AM (#27781996)
One of the harder things for beginners to grasp when learning a second or third programming language is that language is not just syntax. You see it all the time in Python in particular: people writing code like it's C or Java. It's no different to grabbing a French dictionary and transliterating your English sentence to French word by word. It just doesn't work and, in some cases, is completely wrong. Grokking a language means so much more than knowing the key words for doing all the stuff you used to do in your old language.
Re:Functools – The Power of Higher-Order Functions in Python by lwouis on Friday July 09, 2021 @05:49AM (#27782046)
Following your analogy, you will notice that grammar is similar in many European languages. You can rely on subject-verb-object for instance.

Most popular languages these days have aligned patterns for common collections operations. Python stands out IMO.

I wrote a bit more details in a parent comment (https://news.ycombinator.com/item?id=27782030)

Re:Functools – The Power of Higher-Order Functions in Python by lwouis on Friday July 09, 2021 @05:46AM (#27782030)
Most popular languages offer similar operations on collections these days. I've been using Java, Scala, JS/TS, purescript, Ruby, C++, Rust in the past, and these days all have a similar offering to iterate over collections using idiomatic functions such as map/filter/sort/etc.

I'm working on some python these days and I find quite unpleasant the 1-line lambdas, and general messy options to implement common collections operations.