Typing system vs. Java
aleaxit at yahoo.com
Thu Aug 2 13:06:49 CEST 2001
"Christopher Barber" <cbarber at curl.com> wrote in message
news:psoy9p34lvy.fsf at jekyll.curl.com...
> > > did spend more time than I would have liked writing tests to detect
> > > consistency.
> > Probably no more time than I spend cursing [expletive deleted]'s who
> > write type-tests. ...
> > "BEHAVES-LIKE-A" (i.e. IS_ADAPTABLE_TO_PROTOCOL) is what, at most,
> > one SHOULD be testing (if anything).
> Sure, but it is often much easier to document that var x must be a foo
> is to say that it must provide some arbitrary set of attributes. This
Which, again, boils down to looking for your keys under
the streetlamp, because it's too dark over there where
you actually dropped the keys...?-)
> all is one of the point of types: to create a shorthand for sets of
> that you want to go together.
That's what I'd call a PROTOCOL (or, but the term carries
connotations that might be unwarranted, an interface), and
the very reason I'd *LOVE* the protocol-adaptation PEP to
become a reality.
You see, one doesn't normally need just a boolean yes/no
answer to the question "'IS' wenk a pleep?" -- rather, one
needs a 'handle' for wenk that DOES satisfy protocol pleep,
or the information that no such 'handle' can be obtained
(wenk is not *adaptable to* protocol pleep).
That's how one does it in Java -- with the goofy syntax
returning a pleep or raising an exception; in C++, with
the syntax dynamic_cast<pleep*>(wenk) [or pleep& if you
want an exception in case wenk can't peel]; and, best of
all object-models I know, in COM (syntax depends on the
language, as COM is a multi-language object-model, but
semantics rely on calling a specified protocol adaptation
method of wenk called QueryInterface).
All of these approaches have one serious defect from
my POV, and another one from yours. From yours: they
can't really be turned into *compile-time* checks! A
function receiving argument wenk has no way to tell at
compile time whether wenk is adaptable to pleep in
the general case (except, in theory, by examining all
the source code for the program: but even then one
cannot normally tell without solving the halting
problem:-). In order to ENSURE all checks pass at
compile-time reliably, a language must impose far
too many complications and constraints. In fact,
neither Java nor Eiffel really do ensure that (they
have loopholes due to covariance -- Java doesn't
explicitly support covariance, but its arrays in
fact do, and so you can get typeerrors at runtime),
let alone C++ with its unconstrained pointers.
Personally, I don't much mind what can be done at
compile time and what can't -- if *sometimes* the
compiler is able to hoist some check or computation
up to compile time, so much the better, but I don't
want to chafe under unreasonable restrictions to
help the compiler writers do that (and still fail
to do that everywhere anyway, again see Eiffel and
Java's covariance typing-issues:-).
So, the defect of Java's casts, C++'s dynamic_cast,
and even COM's most powerful QueryInterface from MY
viewpoint: they ALL focus on object-identity! You're
supposed to be able to 'cast back' (or QI back) to
the original interface-pointer (or other expressions
of object-identity). This obsessive focus on identity
would be interpreted as a mental illness in many
contexts (at least by therapists of schools harking
back to Korzibski's General Semantics)...;-). Of
course, identity DOES matter in a few of these cases
(COM focuses on it for specific technical reasons
having to do with remoting, for example), but most
definitely NOT for everyday programming issues. If
you look at COM's vast array of 'service' interfaces,
you'll see it has grown one to address exactly this
need -- IServiceProvider basically duplicates the
builtin QueryInterface *except* that it can return
a pointer *without* identity-constraints. I would
far rather have unconstrained protocol adaptation as
the normal modus operandi -- if and when one does
need to worry about identity, in a few rare and
limit cases such as remoting and persistence, hey,
that's what id() is for.
All of which makes the protocol-adapdation PEP a
real jewel in my eyes... except for the little
detail that it doesn't seem that anybody who really
matters cares much about it, so it just stays
parked there. Oh well...:-(.
More information about the Python-list