On Fri, 11 Jun 1999, Guido van Rossum wrote:
I still don't understand the motivation for making it a builtin instead of a method of the types it operates on. Making it a builtin seems very un-object-oriented to me.
Because if you make it a method, every sequence type needs to know about joining strings.
It still seems to me that we could do something like F/'s proposal, where sequences can define a join() method, which could be optimized if the first element is a string to do what string.join, by placing the class method in an instance method of strings, since string joining clearly has to involve at least one string. Pseudocode: class SequenceType: def join(self, separator=None): if hasattr(self[0], '__join__') # covers all types which can be efficiently joined if homogeneous return self[0].__join__(self, separator) # for the rest: if separator is None: return map(operator.add, self) result = self[0] for element in self[1:]: result = result + separator + element return result where the above would have to be done in abstract.c, with error handling, etc. and with strings (regular and unicode) defining efficient __join__'s as in: class StringType: def join(self, separator): raise AttributeError, ... def __join__(self, sequence): return string.join(sequence) # obviously not literally that =) class UnicodeStringType: def __join__(self, sequence): return unicode.join(sequence) (in C, of course). Yes, it's strange to fake class methods with instance methods, but it's been done before =). Yes, this means expanding what it means to "be a sequence" -- is that impossible without breaking lots of code? --david