Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Everything is an object in Python, as well.

Stuff like map() is generic iteration, over any structure that exposes iteration. When it's a member function, it means that every collection has to implement map itself basically. When it's separate, the collections only need to provide the interface needed to iterate over it, and the generic map() will just use that.



> over any structure that exposes iteration

Taking OOP more seriously, this kind of thing should be implemented through inheritance, interfaces, mixins, etc. Even though I've got used to it, Python has these inconsistencies that sometimes it wants to be more OOP, sometimes it wants to be more FP.

Ruby has chosen OOP as its size, and implements nicely those functional operations as methods (same for Kotlin, for example). That makes easy for composing them:

# Sum of the square of even elements of a list, in Ruby

my_list.filter{|x| x % 2 == 0}.map{|x| x * 2}.sum

Python could do something like that, but we quickly fall in a parentheses hell:

# The same code, in Python

sum(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, my_list)))

Languages that have chosen the FP path more seriously implement function composition. They could do the same way as Python, but composition makes it more readable:

# The same code, in Haskell

sum . map (^ 2) . filter (\x -> x `mod` 2 == 0) $ my_list

PS: I know that I it would be better to use comprehensions in both Python and Haskell, but these are general examples


Kotlin is still rather different though in that it still implements stuff like map and filter outside of specific collection classes. If you look at the definition of, say, List, there's no map & filter there, only iterator. Instead, map & filter are defined as extension functions that work on any Iterable.

So semantically it's actually closer to Python, with the only difference that, since Python doesn't have extension methods, it has to use global functions for this, while Kotlin lets you pretend that those methods are actually members. But this is pure syntactic sugar, not a semantic difference.


Still looks much less beautiful. Python feels to me like it can't make up its mind.


I'll take "properly generalized" over "looks beautiful" any time. At the end of the day, the purpose of the code is to do something, not to be pretty.

FWIW you can have both in this case; you just need to make dotted method calls syntactic sugar for global function invocations.


And some will say the exact opposite: contrary to what would seem obvious, code is primarily meant to be read by humans, then written by humans. Because you'll spend way more time unfucking code than actually spitting it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: