Function Overloading Without Typechecking

Quinn Dunkan quinn at hork.ugcs.caltech.edu
Wed Jan 16 15:28:23 EST 2002


On Tue, 15 Jan 2002 12:37:39 -0500, Michael Chermside <mcherm at destiny.com>
wrote:
>Well, that's fine, but I have gotten used to having method overloading 
>in Java and C++. So I like to write things like this:
>
>     def spamThemAll(stuffToSpam):
>         if type(stuffToSpam) in types.StringTypes:
>             stuffToSpam = stuffToSpam.split()
>         for s in stuffToSpam:
>             spam(s)
>
>That way I can invoke the method with two different kinds of values:
>
>     spamThemAll( ['a', 'b', 'c'] )
>     spamThemAll( 'a b c' )
>
>... and it automatically converts. Convenient, but dangerous. For 
>instance, if I had used "type(stuffToSpam) == types.String" as my test, 
>then it wouldn't have worked for unicode strings. And this version will 
>probably break on some other type which I haven't prepared for (UserString).
>
>So what do I do? I can think of a few possibilities:
>
>    1) Just don't do it. Only accept one type and make the caller
>       convert.
>
>       [But this is awkward for the caller!]

Not in the above example:

spamThemAll('a b c'.split())

I've never run into a situation where I have to do much type conversion,
except string->whatever at the input stage.

>    2) Use optional keyword arguments:
>          def spamThemAll( str=None, seq=None ):
>              if str is not None:
>                  seq = str.split()
>              for s in seq:
>                  spam(s)
>
>        [But this makes the caller use keyword args always!]

Yeah, and it's gross besides because now you have a bunch of mutually
exclusive keywords.

>    3) Create multiple methods:
>           def spamThemAll_withString(str):
>               return spamThemAll_withSeq( str.split() )
>
>        [But this creates annoying extra functions!]

Yeah, better to have a thought-out seperate set of functions to convert types
if you need to do lots of it for whatever reason, rather than lots of
*_from_foo *_to_bar.  Combinatorial explosion, etc.

>How do those of you who are more experienced with this handle this issue?

I'd go for #1, but I almost never feel the need to play games with types like
that.  The exception is occaisionally treating singleton as [singleton] in a
function that wants complicated nested structure, e.g.:

((attr1, (f1, ('bar', 'baz', 'faz')),
 (attr2, (f2, ('zaf', 'zab')))
 (attr3, (f3, 'qux')))) # last 'qux' short for ('qux',)

It's like lisp which lets you do

(let ((x nil)) ...)
or
(let ((x)) ...)
or
(let (x) ...)



More information about the Python-list mailing list