d0m's Moka example (https://news.ycombinator.com/item?id=6150944) is closer to composable. I would suggest the following modification. Instead of chaining methods, have a function "chain" which composes functions. We could then write
chain(do(string.split, '+'),
keep(lambda x: x != ""),
map(int),
reduce(moka.add))
If I decided that removing blanks and converting to int was a concept that was worth capturing in its own function, all that I need to do is splice out part of the chain as is. non_blanks_to_int = chain(keep(lambda x: x != ""),
map(int))
chain(do(string.split, '+'),
non_blanks_to_int,
reduce(moka.add))
No modifications were required. It's more complicated with comprehensions. Of course it's still possible, but it's one more unneccessary grain of sand in the mechanism. Doing the same with the imperative version would be nigh-on impossible.Come to my FP days talk in Cambridge, UK, Thursday 24th October, 2013 if you want to hear more about this!
parts=s.split('+')
keep=(s for s in parts if s)
ints=(int(s) for s in keep)
sum(ints)
Hiding the middle steps there in a function is easy enough.That split returns a list, but the other steps are lazy.
I can agree with you in terms of readability, even as a mathematician. For example, the list comprehension syntax mirrors the mathematician's "set-builder notation," so it feels very natural.
However, consider something like a "max", "min", or "argmax" function. Like map and reduce, you can implement this in terms of reduce, but I don't see how you can implement it in terms of a list comprehension. Or consider something like an RPN calculator, which could be implemented as a single reduce call whose initial value is an empty stack and whose input list is the list of RPN tokens.
It seems that list comprehensions can do less in a very objective sense and couldn't be used to replace reduce without other supporting characters. Python has those supporting characters, of course, so there's a good 80/20 argument for favoring list comprehensions over a more opaque call to reduce.