[RFC] Parametric Polymorphism
Tom Anderson
twic at urchin.earth.li
Sun Sep 25 17:03:24 EDT 2005
On Sun, 25 Sep 2005, Catalin Marinas wrote:
> Sorry if this was previously discussed but it's something I miss in
> Python. I get around this using isinstance() but it would be cleaner to
> have separate functions with the same name but different argument types.
> I think the idea gets quite close to the Lisp/CLOS implementation of
> methods.
>
> Below is just simple implementation example (and class functions are
> not supported) but it can be further extended/optimised/modified for
> better type detection like issubclass() etc. The idea is similar to
> the @accepts decorator:
>
> methods = dict()
>
> def method(*types):
> def build_method(f):
> assert len(types) == f.func_code.co_argcount
>
> if not f.func_name in methods:
> methods[f.func_name] = dict()
> methods[f.func_name][str(types)] = f
>
> def new_f(*args, **kwds):
> type_str = str(tuple([type(arg) for arg in args]))
> assert type_str in methods[f.func_name]
> return methods[f.func_name][type_str](*args, **kwds)
> new_f.func_name = f.func_name
>
> return new_f
>
> return build_method
Neat. I'd come up with the same general idea myself, but since i am a
worthless slob, i never actually implemented it.
Is there any reason you have to stringify the type signature? Types are
hashable, so a tuple of types is hashable, so you can just use that as a
key. Replace "methods[f.func_name][str(types)] = f" with
"methods[f.func_name][types] = f" and "type_str = str(tuple([type(arg) for
arg in args]))" with "type_str = tuple(type(arg) for arg in args)". And
then rename type_str to types thoughout.
Also, we can exploit the closureness of new_f to avoid a dict lookup:
f_implementations = methods[f.func_name]
def new_f(*args, **kwds):
types = tuple(type(arg) for arg in args)
return f_implementations[types](*args, **kwds)
tom
--
double mashed, future mashed, millennium mashed; man it was mashed
More information about the Python-list
mailing list