Re: Why don't stringobjects have methods?

Jim Roskind (jar@infoseek.com)
Fri, 1 Apr 1994 09:54:19 +0800

> Date: Thu, 31 Mar 94 22:57:42 EST
> From: tim@ksr.com (Tim Peters)
>
> > ... Why do stringobjects not have methods?
>
> You answered it later: "because strings are immutable". Ditto tuples,
> and ditto ints, long ints, and floats (don't you miss being able to say
> "3.pow(5)" too <grin>?).

Hmm.... I don't see why you assume that a method must return "self"
(or whatever you call the first arg to a method). In fact, you go on
to contradict this assumption in the next answer, which shows that the
sort() method does *not* return self, it returns None. Hence it would
be *totally* reasonable to have (for example) a len() method, which
returns the length of an object. Note that an object is *NOT*
changed by evaluating its length, and hence this method *can* be
defined on immutable objects, such as strings and tuples!. Similarly,
"3.pow(5)" does *not* need to return a modification of "3", rather it
returns "what it returns", which in this case is an object with value
243. Note how the methods "keys()" etc. also return objects other
than self!

> > listobjects have their own methods so that I can say:
> >
> > [1, 3, 2].sort()
>
> Note that this example (indirectly) answers your later question, "Why do
> the listobject methods always return None?". If list.method() returned
> the updated list, then actually using
>
> [1, 3, 2].sort()
>
> as a line of Python would cause
>
> [1, 2, 3]
>
> to get printed. Remember that Python automatically prints every non-None
> expression! Changing Python so that list methods returned anything other
> than None ...

For reference, that was the contradiction I mentioned above.

> ...would cause massive amounts of existing code to start printing
> all sorts of unwanted stuff.

Ahhh... Now you give the real reason for sort() to have its odd return
value. It returns None *because* a mistake was made early on, and
compatibility with existing code requires this oddity. I think this
*IS* a good reason, and you should stick with it ;-).

You do note that another slight problem with Python here however, in
that every evaluation that is not "used" (for instance, in an
assignment or as the arg to another function) is printed. You
correctly point out that *if* we defined the sort() method to return
self, then code would have to do something with the return value to
prevent it from being printed. I tend to use the metaphor that
active methods (i.e., methods that modify the object) return "self".
Haven't we all faced the problem you mention, wherein the return
result from a function call must be "dealt with," in order to prevent
it from printing? *THIS* is the problem that should IMHO be
addressed, rather than discussing existing code using sort().

My approach to dealing with this slight misfeature (python's desire to
print what remains on a line) is:

a) When forced to, assign the return value to a garbage
temporary variable.

b) When I define a class, I add an "ignore()" method which
returns None :-)

Approach a is pretty sub-optimal, as it waste an entry in the dictionary,
takes the time to do unnecessary assignment, etc.

For example of approach b, in my profiler, I can write lines such as:

Stats('profile.1').sort_stats(1).print_stats().ignore()

I can believe that some folks will see the above as an aberration of
nature, but I find it very readable. :-) :-)

IMHO, The correct answer to this slight problem in Python is probably
to have some sort of statement that tosses the result of an
evaluation. In C/C++, the *official* way to do this is by doing a
cast to void:

(void)f(x)

Folks only tend to do this if they get complaints from lint, but it
tends to make the programmer's intention clearer (i.e., the programmer
didn't want to save the return value). I thought about:

None = ...

but "None" is not a reserved word, and hence the above puts a value
into the local dict with name 'None' (oops). I leave it to Python
language designers to provide a way to trash return values from
functions efficiently, but I *won't* use this as an argument against
defining a sort() method correctly!

Finally, the *real* reason why I entered this thread is to push for
being able to write the equivalent of:

for i in foo.keys().sort():
...

Hence I *wish* there was a sort() method that returned self, or a copy
of self! I don't mind if we spec a new sort() method that does the
trick, but it would make my code cleaner and nicer if I had it! Note
that IF a dup_sort() method was defined to return copy of self, then
this "copying sort" could even be applied to immutable sequences...
and the world would rejoice... and peace would rein... and ... (well,
maybe I'm exaggerating a bit).

>
> Tim Peters tim@ksr.com

Jim

Jim Roskind
408-982-4469
jar@infoseek.com