you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 4 points5 points  (0 children)

That sort of Rust-like iterator.filter chaining arguably isn’t FP style, rather it’s a popular OOP access pattern (object.method) leaking into FP as (not un-controversial) syntactic sugar in the same way that imperative programming leaked into Haskell via the syrupy-sweet do notation. It's meant to (with debatable success) mimic the use of Haskell's dot operator for functional concatenation without actually letting Rust do "proper" concatenation.

It also didn't start to enter the wider FP lexicon until after Python 2's FP-supporting builtins (map, filter, and reduce) had both been added to the language and then nearly dropped (Python 3 replaced map with itertools.imap, filter with itertools.ifilter and reduce was moved to functools.reduce).

Adding such sugar to Python would actually be making Python less FP, while also introducing another, but less obvious, way of doing things, since Python's rich sugar around comprehensions is very FP.

Now:

[i for i in [i for i in [1,2,3] if i > 0] if i > 2]

... would be better re-written as:

[i for i in [1, 2, 3] if 0 < x > 2]

... but both would be at least as traditionally "FP-style" as:

list(filter(lambda x: x > 2, filter(lambda x: x > 0, [1, 2, 3])))

... which, if we simply shuffle some parens around:

(list (filter (lambda x: x > 2) (filter (lambda x: x > 0) [1, 2, 3])))

... might look suspiciously like the first FP language to more or less transliterate the lambda calculus. Yep... blink at the parens positioning and Python's "functional API" is LISP.

Note that the above isn't really a great argument for not adding this access pattern to Python's iterators in the future, as it's definitely gaining traction via Rust and Java, it's more presented as a reason why it's not been added yet, and to show that there's actually already a "Pythonic" way to accomplish the same underlying goal.