Method or function?

Quinn Dunkan quinn at dinar.ugcs.caltech.edu
Thu Nov 2 07:25:42 CET 2000


On Tue, 31 Oct 2000 19:17:37 GMT, Rainer Deyke <root at rainerdeyke.com> wrote:
>"Dale Strickland-Clark" <dale at out-think.NOSPAMco.uk> wrote in message
>news:c3dtvs0uuleerbk6i44psnvmhqug6ghoec at 4ax.com...
>> I dare say that this has been discussed before, I just can't see it
>> anywhere.
>>
>> Shouldn't these standard functions be methods of their various
>> datatype classes?
>
>The number of methods of an object should be minimal, so that it is easier
>to implement new classes/types with the same external interface.

Usually this is solved by inheritance.  I was under the impression that the
standard functions were a result of history (which can change, see the string
methods), the fact that you can't inherit from C types in python (more
history), and the fact that there is no 'base object' in python like in, say,
smalltalk.  And I mean 'code inclusion' inherit, not 'subtype' inherit.

I actually agree with you, I'm just being argumentative because I'm in that
mood :)  There are good reasons why python has those functions and not
methods, but it has more to do with the nature of python than the functions
themselves (e.g. other OO languages like sather and ruby and smalltalk *do*
provide them as methods and it works fine).

So my response to the original question is:

The main reasons are history, the current implementation, and the fact that
there is no universal ancestor in python.  Historical results can be changed
(witness the recent migration of string functions into methods).  The current
implementation likely won't change significantly until 3K (where we can
hopefully inherit from builtin types).  And I sort of doubt python will ever
have a generic Object class.  Who knows, though.

>> chr
>
>As a method of integer?  That would make the integer type dependent on the
>string type, which is generally a bad idea.

As a method of anything that can be turned into a character.

>> dir
>
>The whole point of dir is that it can be applied to all objects (including
>class instances) and it automatically works.

If they all have one ancestor, no problem, put dir() there.  But I'm glad
classes can't override this in python :)

>> eval
>
>As a method of string?  Is there any advantage to this?  Methods in general
>should be applicable to all instances of a type/class.

Or a method of a thunk, or a compiled syntax tree, or...  And the 'getitem'
method isn't applicable to [], is it?

>Filter applies to all sequences.  Do you want to write a new filter function
>for each new sequence?

No, just inherit from Sequence :)

>> float
>
>This is a constructor function.

But constructors *are* methods.

>> id
>
>id applies to all objects, including methods.  Do you really want
>1.id().id().id() to be legal Python?

Why not?  We already have 'h'[0][0][0][0] :)  In ruby: '1.id.id.id.id.id'
And in python we already have id(id(id(id)))... would you prefer that be
illegal?  Why?

>> map
>
>As method of what?  The function?  The sequence?  Which one?

The sequence, silly.  Smalltalk calls it 'collect'.

>> max
>> min
>
>1.max(2) # Evaluates to 2
>1.min(2) # Evalutes to 1
>
>I rest my case.

What?  It looks fine to me.  Does it bother you that '1>2' evaluetes to 0,
while '1>0' evaluetes to 1?  Also consider:

def clamp(lst, maxval):
    return lst.filter(maxval.max)

>> ord
>
>This would make sense as a method, somewhat.

But I thought
>                                                         Methods in general
>should be applicable to all instances of a type/class.
what's the value of 'ab'.ord()?

And wouldn't that make the string type "dependent" on the integer type (which
is a bad idea)?

:)

>Applies to all objects.  repr has a default behavior for class instances,
>which can be modified by defining __repr__.  If this was a method, there
>could be no default behavior.

If we had a universal ancestor.  But we don't.  Not that I think we should.

>> round
>
>This might make sense as a method.

But it's a constructor function!  It makes floats!  How is

number.float()

different from 

number.round(9999999)

? :)

>> str
>
>See: repr

sather:
#OUT + obj.str + "\n";

>> vars
>
>See: dir

ruby:
1.methods #-> ["abs", "**", "next", "<=>", "-", "to_f", ...]



More information about the Python-list mailing list