Re: OT: Language War (Re: "C" Manual)
On Tue, Jan 01, 2002 at 10:34:25AM -0600, Richard Cobbe wrote:
| Lo, on Tuesday, January 1, dman did write:
|
| > On Mon, Dec 31, 2001 at 09:27:36PM -0500, William T Wilson wrote:
| >
| > | Casting you can't really get away from nor do you really need to. In fact
| > | the more strongly typed the language is, the more casting you have to do.
| >
| > This statement is incorrect.
|
| Agreed.
|
| > The strength and staticness of typing are two independent properties.
|
| Also agreed.
Cool, I'm glad you know this stuff too!
| However, I think that the flexibility of a type system is more important
| than its `strength' for removing the need for casts.
This sounds like a reasonable statement.
| When do people use typecasts in C/C++? In my experience, they tend to
| happen in the following situations:
| 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].
| 3) Accessing external data in a callback function. Callbacks in C and
| C++ often take a void* parameter that points to data supplied by
| the programmer when he registers the callback; to access this data,
| it is necessary to cast it back to the original type.
I don't know about C++ frameworks that do this, but C's type system
certainly requires this. In Java the callback is a class instance
anyways (since functions are not objects, nor can you take the address
of one).
| How do more flexible type systems handle these?
| 2) As several people have pointed out, too many downcasts indicate a
| design flaw.
I agree here.
| They 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. 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!).
| 3) There are a variety of strategies here. My personal favorite is
| to use first-class closures to implement callbacks; the external
| data is no longer supplied as a parameter but is simply available
| to the callback function due to normal scoping rules.
This sounds good to me :-).
| If you're using a language without closures, like C++ or Java,
| you can hack it up:
In java you _have_ to hack it up like this (for example,
java.lang.Runnable).
| 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).
| > I've heard that haskell has an even better type system, but I haven't
| > had time to learn it yet.
|
| Most of my experience with advanced programming languages has been in
| Scheme, which (despite what many people believe) *is* strongly-typed and
| type-safe, but it checks all types at runtime rather than compile time.
| As a result, I'm not really up on languages with compile-time type
| verifications systems, though I've been meaning to investigate them for
| a while now. At any rate: I've heard that ML's type system is easier to
| learn than Haskell's; you may want to start there first.
Ok, I might do that. I've heard a lot about various languages on
comp.lang.python, and one particular guru (he's a C++ guru also)
frequently mentions Haskell's typeclasses in flamewars regarding type
systems.
-D
[1] with "primitive" types, I think java may do some conversion
(certainly with float->int it must), but I'm not totally sure (I
think with int->byte it doesn't, just truncates)
--
The Lord detests all the proud of heart.
Be sure of this: They will not go unpunished.
Proverbs 16:7
Reply to: