[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: OT: Language War (Re: "C" Manual)



On Tue, Jan 01, 2002 at 09:39:18PM -0600, Richard Cobbe wrote:
| Lo, on Tuesday, January 1, dman did write:
| 
| > On Tue, Jan 01, 2002 at 10:34:25AM -0600, Richard Cobbe wrote:
| > | Lo, on Tuesday, January 1, dman did write:
| > | 
| > | > The strength and staticness of typing are two independent properties.
| > | 
| > | Also agreed.
| > 
| > Cool, I'm glad you know this stuff too!
| 
| Oh yeah.  I've got *way* too much Scheme/LISP experience to think that
| static typing and `strong' typing are the same thing.

:-).

| > |   2) downcasts in a class hierarchy, as in Java.  (Note that `upcasts'
| > |      aren't really casts: if B is a subclass of A, then an instance of B
| > |      *is* an instance of A, no cast needed.)
| > 
| > This is only needed with unintelligent compiler.  *You* know you have
| > a B at runtime, but the compiler doesn't so it whines and complains.
| > Thus you must "cast" the pointer/reference to appease the compiler.
| > The cast in java doesn't do anything else (aside from a runtime
| > verification as well)[1].
| 
| Well, in some cases, a sufficiently sophisticated compiler could
| determine at compile time that what it thinks is an A will, in fact,
| always be a B, thus removing the need for a downcast.  However, I don't
| think this sort of proof is possible in the general case.

I think this is what Haskell compilers do.

| And you're quite right, the downcast simply appeases the compiler by
| telling it, `No, this really is a B.'  The important thing is that you
| have the runtime check to verify this.  Without that, nasty things
| happen.
 
| > |      [Downcasts] are, however, useful in some situations, so (I
| > |      believe) many advanced languages with a static type system support
| > |      these.  However, as in Java, there's a run-time check that goes
| > |      with it.  C++'s dynamic_cast gets this right.
| > 
| > Take CORBA for example.  With python, you just have an object with the
| > given methods.  No problem, no difficulty.  
| 
| I've not worked with Python very much.

You're missing out on the fun.  With your Lisp/Scheme background you
will like the fact that python has built-in lists and has some
functions (map, reduce, filter) to work with them in a functional
style.

| Does it do compile-time type analysis like C++ or Java?

No.  It is completely runtime checked.

| I know that if there were CORBA bindings for a language like LISP or
| Scheme, you wouldn't have to worry about casts---the methods you
| expect are automatically there.  Presumably the same applies to
| Smalltalk, but I'm not sure.

This is how python works for all objects, not just CORBA.  You simply
use it the way you want to (based on what you expect the type to be)
and, of course, document that as a precondition for the function.  If
you need a file-like object, state that, and it is the client's
responsibility to provide one.  The beauty of it is (1) no time is
spent telling the compiler what you have and (2) polymorphism is
achieved without requiring inheritance (of classes or interfaces).

The python-orbit package contains python bindings for ORBit.  This
particular binding doesn't have any IDL compiler program.  When you
load it (import the module) it hooks itself into the import mechanism.
If it finds an idl file that matches the module you (later on) try to
import it will parse it then and create the necessary classes.  You
_know_ the classes are there and you know the methods are there
because they are (you wrote the IDL or someone else did and you read
it).  It is really convenient and a time saver!

| > With java you have to use a special "narrow" method to create an
| > instance of a class that implements the interface, but does so in
| > terms of corba calls.  With the inflexible type system java uses, the
| > downcast-wannabe is necessary (ugh!).
| 
| This is one instance, I believe, where there's a very visible tradeoff
| between the flexibility of run-time typechecks and the early error
| detection provided by compile-time typechecks.  Let's take OCaml
| (another language that I'm really not all *that* familiar with).  It has
| an object system and checks types at compile time, but it also has a
| much more flexible type system than Java's.  Instead of saying than an
| object is of type Foo, you instead say that the object has type
|     < a : int -> int, b : ('a -> bool) -> 'a list, ... >
| which means that the object has *at least* methods a and b, and that a
| and b have the indicated types.

Yeah, this is like specifying (part of) the interface the type must
conform too.  It is much more flexible because it does not specify the
type (class) but just a piece of the interface.

| However, if you know full well that the object in question *also* has a
| method c (of whatever type), you won't be able to invoke it, because the
| compiler hasn't been able to prove that the object will always have such
| a method.  I would imagine there's some sort of checked downcast
| operation to handle this situation.
| 
| In short: downcasts are perfectly safe if and only if there's a runtime
| check involved.  

Agreed, but I still dislike them because of the extra work I must do
(as a programmer) to write that in the source.

| > |         template<typename T>
| > |         void register_callback(void (* cb)(T), T data);
| > 
| > That's not so bad, if you can stand the bloat this creates (C++
| > templates are expanded at compile time, thus you get one copy of this
| > function for each type it needs to work with).
| 
| Mph.  Don't write off polymorphism (which is what C++ templates
| approximate) just because most C++ compilers do a really bad job of
| implementing it.

Definitely, but the example you gave was C++ :-).  With python,
everything is a essentially a "void*" that is checked at runtime.
Thus you don't get compile-time code bloat, the safety of runtime
checks, and the simplicity of not needing a downcast.  (python has no
cast mechanism at all)

| It's a useful concept, and there are better strategies out there;

Yes.  Eiffel generics are (syntactically at least) much nicer.


Say, have you ever used VDM-SL to model a system?  I'm learning it
right now in class, and the funniest thing for me is how close to
actual python code it looks like.

-D

-- 

Windows, hmmm, does it come with a GUI interface that works or just
pretty blue screens?



Reply to: