Haskell Typeclasses

Kay Schluehr kay.schluehr at gmx.net
Thu Dec 15 15:05:29 EST 2005


Alex Martelli wrote:
> Aahz <aahz at pythoncraft.com> wrote:
>    ...
> > Hrm.  I don't recall anything about typeclasses, so my suspicion is that
> > you were writing something lengthy and above my head.  Can you write
> > something reasonably short about it?  (I'm asking partly for your
> > benefit, because if it makes sense to me, that will likely go a long way
> > toward making sense to Guido -- we seem to think similarly in certain
> > ways.)
>
> Think of a typeclass as something "like an interface, more than an
> interface" to which a type can easily be "adapted" by a third programmer
> even if the two programmers who wrote the type and typeclass were
> working separately and with no knowledge of each other -- not too far
> from the vaguer idea of "protocol" I support in PEP 246 (which focuses
> on the adaptation), except that in Haskell things happen at compile time
> while in Python we prefer to avoid the strong distinction between
> compile time and runtime.
>
> You may think of a typeclass as akin to an abstract baseclass, because
> it's not constrained to only giving the signatures of methods, it can
> also supply some default implementations of some methods in terms of
> others.  Guido blogged in August about interfaces versus ABCs, not
> remembering why he had once Pronounced about preferring ABCs, and in his
> critique of ABCs he mentions that one weakness of their ability to
> provide default implementations is that you have to decide about what is
> the most fundamental subset, in whose terms the rest is implemented.
> But *typeclasses do away with that need*.  Consider (arbitrary
> pythonesquoid syntax):
>
> typeclass mapping:
>   def __getitem__(self, key):
>     _notthere=[]
>     result = self.get(key, _notthere)
>     if result is notthere: raise KeyError
>     return result
>   def get(self, key, default):
>     try: return self[key]
>     except KeyError: return default
>   # etc etc
>
> this LOOKS like mutual recursion, but since it's a typeclass it doesn't
> mean that: it means __getitem__ may be defined (and then get uses the
> provided default implementation unless overridden) OR get may be defined
> (and then it's __getitem__ that may use the default implementation
> supplied by the the typeclass, or else override it).
>
> When you compile a typeclass you build a directed graph of dependencies
> of methods on each other, which may include cycles; when you show how a
> type adapts to a typeclass, you build a copy of that graph removing the
> dependencies of those methods which do get explicitly implemented (in
> the type or in the adapter) -- if the copy at the end of these
> compilations still has cycles, or leaves (methods that the typeclass
> requires and neither the type nor the adapter supply), then this raises
> an exception (incomplete adaptation).
>
> Thus, a typeclass clearly shows the semantics intended for methods that
> depend on each other, and conveniently lets you, the adapter's author,
> choose what to implement -- the typeclass's author has not been forced
> to pick the "most fundamental" methods.  ABCs, or extremely handy mixins
> such as UserDict.DictMixin, do force a programmer who knows nothing
> about the internals of your class (the author of the ABC or mixin) to
> pick "most fundamental" methods.  Thus, typeclasses are more useful than
> ABCs by as much as ABC are more useful than (simply "syntactical")
> interfaces -- coupled with adaptation mechanisms, the overall result can
> be extremely handy (as any Haskell programmer might confirm).
>
>
> Alex

I don't see why your typeclass illustration does not apply to ABCs as
well? The sanity checks for typeclasses you describe seem to be a
particular feature of Haskell or other pure functional languages
without destructive updates and messy aliasing problems. It's hardly
believable that this would be possible in Python and runtime checks
won't help much in this case.

By the way I also don't understand Guidos concerns. Maybe he is against
the whole idea of creating frameworks and partial implementations? It's
not very clear for what reasons he likes interfaces. 

Kay




More information about the Python-list mailing list