LangWart: Method congestion from mutate multiplicty
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Feb 10 19:36:20 EST 2013
Rick Johnson wrote:
> On Sunday, February 10, 2013 5:29:54 AM UTC-6, Steven D'Aprano wrote:
>> Rick wrote:
>> And you have missed my point, which is that reversed(), and sorted(),
>> were not added to the language on a whim, but because they were
>> requested, over and over and over again.
>
> Well, well, this explains everything!
>
> We don't add features because of logic, or because of consistency, or even
> because of good sense, we simply add them to appease the masses.
They were requested because people kept re-inventing them. They kept
re-inventing them because they are useful functions that make good sense to
have.
>> "appended" is called list addition.
>>
>> newlist = oldlist + [item_to_append]
>
> But where is the consistency?
Strings use + for concatenation. Tuples use + for concatenation. Lists use +
for concatenation. Seems pretty consistent to me.
Are you sure you've used Python before?
> Yes the syntactic sugar of the "plus sign" is concise, however, the "+"
> operator does not "pair" intuitively with the "append" method.
Adding "ed" to a word does not pair intuitively with the method name. You
have to learn it, which in the case of most English speakers you probably
did between the ages of 2 and 6.
Using + to represent concatenation is no less intuitive.
> Even IF you
> transformed the "+" operator into a named method like "add" (or call the
> magic method "__add__") it still fails to mesh properly with "append", and
> the two words utterly fail to intuitively establish an "in-place" versus
> "copy-mutate" relationship.
So what?
>> > flatten, flattened
>>
>> flatten is another often requested, hard to implement correctly,
>> function. The only reason that Python doesn't have a flatten is that
>> nobody can agree on precisely what it should do.
>
> Steven, the definition of flatten (as relates to sequences) is very, VERY
> simple:
>
> Return a new sequence that is the result of reducing
> a nested sequence of sequences into a single depth
> sequence.
Very, VERY simple until you actually implement this function, and discover
that it does too much e.g.
flatten([None, 23, [1, 2, 3], Point(x=2, y=3), ["spam", "ham"]])
=> [None, 23, 1, 2, 3, 2, 3, 's', 'p', 'a', 'm', 'h', 'a', 'm']
So people who have *actually programmed*, instead of just talking about
programming, have discovered that in practice you need to treat some
sequences as primitives that don't get expanded.
>> Like map, filter, reduce, etc. flatten is not sensibly implemented as a
>> mutator method, but as a function.
>
> Only because you, along with a few other high ranking members of this
> community (including the BDFL himself!) have this /aversion/ to true OOP
> paradigm.
>
> Can you provide an example of how flatten "as a method" is incorrect
> versus flatten "as a function" is correct, or will this challenge be
> silently swept under the rug as so many before?
Simple efficiency. The most efficient, and sensible, way to flatten a list
is to create a new list. Trying to flatten a list in place is a dumb
idea -- it is O(n**2), or possibly even worse. Since only an idiot would
write flatten as an in-place method, any mutator version of flatten would
have to use a non-mutator version, then use slicing to over-write itself:
def flatten(self):
new_list = flatten(self)
self[:] = new_list
which is fine if you absolutely have to have an in-place version, but why
bother? The caller can do it themselves:
mylist = flatten(mylist)
[snip]
>> > map, mapped
>> > filter, filtered
>> > reduce, reduced
>>
>> Those are nonsense. None of those are in-place mutator methods.
>
> Well not in the current implementation of Python; but they could be if we
> wanted them to be.
Now you're smoking crack. How can *reduce* be an in-place mutator method?
py> mylist = [1, 2, 3, 4, 5]
py> from operator import mul
py> reduce(mul, mylist)
120
I would really like to see your implementation of a reduce method that turns
a list into an int *in-place*.
> Applying mutations both "in-place" and "to a copy" are
> very helpful.
Exactly.
[snip]
>> > My point was this: All mutate methods should mutate "in-place",
>>
>> Well duh. All mutator methods do mutate in-place, otherwise they wouldn't
>> be mutator methods.
>
> So "reversed()" and "sorted()" mutate in-place?
No. They are not mutator methods, because they do not mutate in place.
>> > if the
>> > programmer wishes to create a mutated copy of the object, then the
>> > programmer should /explicitly/ create a copy of the object and then
>> > apply the correct mutator method to the copy.
>>
>> Been there, done that, it sucks. That's about a dozen steps backwards to
>> a worse time in Python development.
>
> Why? Because you have to type this
>
> reversed = list(seq).reverse()
Are you sure you've programmed in Python before? That gives reversed = None.
--
Steven
More information about the Python-list
mailing list