The point mostly is that those problems probably stem from is-a semantics. It might be that has-a semantics might work better.
In such a case a has-a semantics means that circle "has-a" function to compute its area, a function to compute its circumference, etc. An ellipse "has-a" function to compute its area, a function to compute its circumference, etc. It doesn't matter whether the user thinks of circles as special cases of ellipses or not.
Perhaps the way to go would be to support interfaces without requiring type checking. Basically you simply say "all I care about is that this object can be passed to that function".
That said a semiformal way of expressing this - probably by giving a name to an interface (which is just a set of function symbols that an object supports) - might be useful. This way wouldn't necessarily be checked by the program - it might be useful to have it be read by the programmers as part of the code/documentation.
(typeclass 'scanner 'car 'cdr)
; programmer reads: a scanner is anything that somehow supports 'car and 'cdr
(def foo (a)
" A ridiculously complex library function which does
a lot of useful things and which the library user
probably doesn't want to read in full, because he or
she is using the library so that he or she doesn't
have to think about it.
See also [[bar]] "
(must-have a 'scanner)
; programmer reads:
; "Anything I define which supports 'car and
; 'cdr can work on this function"
(ridiculously-complex-expression-involving a))
OK, maybe I flipped out a bit when I heard the word 'type' mentioned. It brought up nightmares of using Java and C++ and so forth.
The kind of thing you're suggesting here does look powerful (and most importantly, optional!) If you combine it with sacado's suggestion for putting the methods in the tag, then you have a very powerful type system indeed.
I just have one contentious thing left to say: when you move away from is-a typing to has-a typing, does it really make sense to use the word 'type' at all? Aren't we really talking about what your functions can do, rather that what your objects are? For example, if you define car and cdr to work on strings, have you added strings to a new sequence type or have you expanded the power of your functions? I prefer to think that you've done the latter, and save the word 'type' for the basic is-a types that every language has to have.
It's the word 'type' I'm objecting to now, not the general idea. Perhaps we need to get out of the typing mindset in order to really break new ground.
The value of types is the name you associate with an object. Instead of giving a really long list of "functions that should work on the object" you say "an object of this type". So instead of saying "an object that has 'car and 'cdr" you just say "scanner".