4 ms·
Count me as one of those people that don't get it. If I'm joining the elements of an array together, I'm operating on the array. Therefore I _expect_ the join()
by jherdman 18y ago
Count me as one of those people that don't get it. If I'm joining the elements of an array together, I'm operating on the array. Therefore I _expect_ the join() method to be on the array.
To me, Python can't seem to make up its mind with these weird (IMHO) stand-alone methods like join(), sum(), any(), etc. That's the kind of thing I'd expect in a functional language, not in an OO language.
- jerf 18y agoThe thing is, they aren't methods. They really aren't. They don't operate on an object using the object's local data. They are generic functions that use certain defined interfaces that many objects define. "list.join(str)" and "str.join(list)" are not the same. The list.join syntax only works for lists, but str.join takes any sequence, which is anything that implements the sequence protocol, including lists, dicts, sets, trees, heaps, iterators in general, and a limitless variety of user-defined sequences. Once you understand that it's not a matter of picking two spellings of the same functionality, but actually radically different functionality between the two spellings. (Putting this on string rather than it being a free-floating function is perhaps dubious, but at least the operation does have a sort of irreducible stringy-ness to it in a way that it does not have a listy-ness to it.) If you make the "join" a method of list, then you have grotesquely cut its functionality. Now you are requiring people to implement their own join on every other object that implements the sequence protocol, which is just silly. (Of course if they have other needs they may still implement something else, but why not give them the option of the default?) This is generic-programming through duck-types, not OO. Similarly for all the other examples you cite and quite a few more; putting them on "list" is not "the sensible thing to do", it would be a grave error. Python 2.5.2 (r252:60911, May 7 2008, 15:19:09) ... >>> ", ".join(str(x) for x in xrange(10)) '0, 1, 2, 3, 4, 5, 6, 7, 8, 9' That's not a list in there.
- zupatol 18y agoWell join should be on sequence instead of list then. To me it seems unnatural to see join on string because string feels more 'basic' than a sequence, so I would expect the sequence to know about strings rather than the opposite. But the argument against join on string is not as strong as the argument against sum on array.
- calambrac 18y agoThis is such a non-issue. Really. The parent posted the reasoning behind the decision, that reasoning is sound. Your disagreement is purely aesthetic, there's simply no practical reason why the current way is wrong. Please just accept that this is how it is, and stop complaining about it. Please?
- philh 18y agoPython is intended to be aesthetically pleasing in some sense, so I don't think aesthetic objections to some of its features are unwarranted.
- calambrac 18y agoThis isn't one of the 'some'. http://en.wikipedia.org/wiki/Color_of_the_bikeshed http://en.wikipedia.org/wiki/Color_of_the_bikeshed
- scott_s 18y agoI don't think this is bike-shedding. That applies when people argue over two functionally equivalent options, often to the detriment of more important issues. In this case, their objection is that it violates their intuition, but the placement of join is a natural result of how Python's types are defined. Defining join on all sequences would have real (annoying) implications.
- calambrac 18y agoThat applies when people argue over two functionally equivalent options, often to the detriment of more important issues. How does that not fit this situation? Because there's actually a good technical reason to do it the way it's currently done? Wouldn't that imply that there should be even less discussion of it?
- scott_s 18y ago
- _pius 18y agoI agree with you if you mean that an array should be able to abstractly reduce its elements, but I'd argue that the specifics of how the array gets reduced are generally outside of the responsibility of the array class. In Ruby, this is accomplished through Array#inject, which allows you to specify the procedure that gets applied as you're joining. This makes it easy to do summing, string concatenation, etc, etc.
- bobbyi 18y agoThe reason join() isn't a method on lists is that it would mean that every class that wants to act like a list would have to implement it (or inherit from someone who does). If you write your own class that is iterable but doesn't inherit from list, it would not have a join() method unless you wrote one. But it works as an argument to '\n'.join() for free since that can operate on anything iterable. The other problem with sticking methods like join(), sum() and any() onto collections is that whenever a new method is added (for example, any() was added in python 2.5), it would cause confusion for anyone who has a list-like class that happens to have a method with that name that does something different.