Returning different types based on input parameters

Adam Olsen rhamph at gmail.com
Thu Apr 9 11:25:09 CEST 2009


On Apr 8, 8:09 am, George Sakkis <george.sak... at gmail.com> wrote:
> On Apr 7, 3:18 pm, Adam Olsen <rha... at gmail.com> wrote:
>
> > On Apr 6, 3:02 pm, George Sakkis <george.sak... at gmail.com> wrote:
>
> > > For example, it is common for a function f(x) to expect x to be simply
> > > iterable, without caring of its exact type. Is it ok though for f to
> > > return a list for some types/values of x, a tuple for others and a
> > > generator for everything else (assuming it's documented), or it should
> > > always return the most general (iterator in this example) ?
>
> > For list/tuple/iterable the correlation with the argument's type is
> > purely superficial, *because* they're so compatible.  Why should only
> > tuples and lists get special behaviour?  Why shouldn't every other
> > argument type return a list as well?
>
> That's easy; because the result might be infinite. In which case you
> may ask "why shouldn't every argument type return an iterator then",
> and the reason is usually performance; if you already need to store
> the whole result sequence (e.g. sorted()), why return just an iterator
> to it and force the client to copy it to another list if he needs
> anything more than iterating once over it ?

You've got two different use cases here.  sorted() clearly cannot be
infinite, so it might as well always return a list.  Other functions
that can be infinite should always return an iterator.


> > A counter example is python 3.0's str/bytes functions.  They're
> > mutually incompatible and there's no default.
>
> As already mentioned, another example is filter() that tries to match
> the input sequence type and falls back to list if it fails.

That's fixed in 3.0.  It's always an iterator now.


> > > To take it further, what if f wants to return different types,
> > > differing even in a duck-type sense?
> >
> > At a minimum it's highly undesirable.  You lose a lot of readability/
> > maintainability.  solve2/solve_ex is a little ugly, but that's less
> > overall, so it's the better option.
>
> That's my feeling too, at least in a dynamic language. For a static
> language that allows overloading, that should be a smaller (or perhaps
> no) issue.

Standard practices may encourage it in a static language, but it's
still fairly confusing.  Personally, I consider python's switch to a
different operator for floor division (//) to be a major step forward
over C-like languages.



More information about the Python-list mailing list