Registered: Aug, 2005
Re: Interfaces or Abstract Base Classes?
Posted: Aug 18, 2005 5:33 PM
I quite agree that 'ad hoc polymorphism' (aka
'overloading') is 'richer' (or more powerful)
when combined with a 'richer' (or more extensive)
method/operator/function signature. By combining
strong typing and interfaces, you get two additional
dimensions of functionality. This multiplies ones
options. It is more 'flexible'. It is can
be considered more 'expressive'. Yet either new
dimension of functionality can be supported either
in isolation or in combination.
I rush to agree that without sufficient
programming language 'flexibility'/'expressiveness', one
could end up forced to hand code run-time type checks on
untyped arguments. As far as I can tell, you
illustrate the necessary work arounds perfectly.
Still, it seems like a non-sequitur to conclude that
strong typing (e.g. typed method/function arguments)
are always 'better' for any programming languge.
Python, for example, has abstained from the
complexities of strong typing for a number of very
There is a price to pay for Python's 'simplicity'.
The performance price is well understood (and
often discussed). The lack of strong typing also
affects the 'flexibility' of any 'ad hoc
polymorphism' (aka 'overloading'). This might be yet
another price to pay for the sake of simplicity.
Perhaps the aggregate price of Python's
simplicity (via weak typing) is starting to add up.
As new features come into the Python language, weak
typing might be more and more onerous. Perhaps the
price of weak typing simplicity is getting too
high? Perhaps not?
Should we always seek to add more and more features
to Python? Must Python become as 'expressive'
(and/or baroque) as C++? Is more always better?
Perfection is achieved, not when there is
nothing more to add, but when there is nothing
left to take away. Antoine de Saint-Exupery
By the way, I figure that you are also quite
correct about the potential software engineering
benefits of type checking. Strong typing adds
signficant value - from earlier 'type checking'
feedback. A type checker automaton can be darn
diligent about reliably catching whole classes of
errors and omissions ...
This software engineering benefit *is* very
similar to the benefits of an 'interface' contract.
Yet Python's simplicity is at stake.
The more-is-better argument is a slippery
slope. Sometimes, languages optimized for
different purposes are better than one language
that tries to be all things for all purposes.
While we're talking about programming langauges,
this point is perhaps even clearer with respect to
domain specific langauges (DSLs) -- if anyone happens
to follow these.
Permit me to try an analogy. I own a cross-bike.
A cross-bike is a blend of a mountian bike and a
road bike. It is great for puttering around with
small children (on paved surfaces). It isn't great
for a road race. It isn't great for single track
trails (up/down mountains). The cross-bike is a
nasty compromise - but it'll get you everywhere.
All the same, the better solution is to have *both*
a mountain bike and a road bike. With *two*
different bikes, I get the best of all worlds. I
always have the choice of a bike optimized for
what I want to do. Now that I've got two such
bikes, I realize that the cross-bike is really
not very good for anything in particular. Dare
I say that cross-bikes should be considered
If you'll permit me to spin a weak metaphor from
this lame analogy, I'm hoping that Python does not
become a cross-bike.
Personally, I quite like Python as my
quick-n-easy, RAD/agile language. I sort like the
way Python pairs up with C++ (and/or interfaces to
C++). Take performance conerns. Careful C++
code can be really fast. Good luck trying to get
a cross-bike-style language (like Java) to match
C++ performance. I know, this is a long-standing
flame war. A whole lot of folks wish that Java was
faster than C++ for every application ... but it
isn't. A lot of folks wish that RAM/disk footprints
of JAVA programs (and J2EE/JVM support environments)
were just as small as statically linked C++ programs -
but they aren't. Reality sucks. A cross-bike is
The Python/C/C++ language bundle is
probably better than *any* single language could
*ever* be. I'd hate to see Python become yet
another Java/C#/C++ equivalent. What's the point?
I quite agree with the 'interface' semantic you
seem to illustrate. Lets say that there is a
graphical object class hierarchy. Lines, shapes
and dots (pixels?) might be specializations.
Shapes might specialize into regular/geometric/vector
shapes and irregular/raster shapes. All geometric
shapes might have properties/methods/accessors
name (an enum like "triangle", "square", "rhombus" ...)
locus (or locii ...)
texture_light_source_x_offset (from center point)
texture_light_source_y_offset (from center point)
Now there might also be a interface hierarchy
for 'color'. The root 'color' interface might
require only a bunch of fill_* color property/accessors.
This can be specialized into a 'Edged_Color' interface
when a bunch of 'edge_*' properties/accessors are
There might also be a interface hierarchy for
'Texture'. The root 'texture' interface might
simply require some property/accessor named
'fill_texture_name'. A variety of more specialized
texture interfaces might refine the vague concept of
'Texture' in various ways (e.g. the
Shaded/3D texture 'interface', the
gradient/2D texture 'interface', etc.).
My point is simply that strong typing is *NOT*
required. I've made no use of strong types in
this elaborate Shape/Color/Texture example. If
anything, I've hinted at user-defined type extensions
like enumerations - and other such base/machine-type
I'm also trying to illustrate the 'alternate
abstraction' (i.e. perspective) 'interface'
semantic. It seems we agee on this purpose for
the 'interface' concept.
I'm suggesting that all of the 'implementation'
logic/code for the shape classes be organized into Shape
class hiearchy. Such 'interfaces' would be assert/express
commonalities/hierachies from other possible
As I mentioned, I'd avoid scattering 'implementation'
code/logic into any of the alternate 'interfaces'
hierarchies. This would lead to either some form of
'aspect oriented programming' (and code weaving) or
to multiple inheritance (from multiple, concurrent type hiearchies). Neither of these results is very
'simple'. I'm all for keeping Python as simple as
At the end of the day, I'd try to solve 80% of the
common/typical needs with something 20% as
complicated. It is the last 20% of the needs - the
corner cases - that usually requires 80% of the
complexity. In other words, I'd suggest
* Weak typing (continue w/duck typing)
- This seems best as a separate debate/discussion
* Alternate abstraction 'interfaces' only
- Various 'perspectives' on the class hierarchy
- limited! No core/class implementation logic/code.
No property additions via interface decl.
No multiple inheritance. No implementation
- accept constraint logic/code in interfaces
> match to constraints applied to class decls
(e.g. support optional enums?)
- accept mapping/glue logic via interface decl
> when possible, such mapping/glue logic
conforms a given set of class instances to a
> class specific 'wrapper'logic within the