Smalltalk = strongly typed?
Andreas Raab
andreas.raab at gmx.de
Thu Oct 14 07:09:06 UTC 2004
Hi Blake,
> Dynamic, I get. Typed, I get. But strongly typed? Am I mistaken in
> thinking there isn't really any type-checking at all?
Weak vs. strong typing is not primarily about type-*checking* but rather
about whether an object (reference) uniquely belongs to a type or not. To
give an example, in C[++] (which is statically but weakly typed) I can do
things like:
((Foo*)0)->size()
e.g., take an integer, "cast it" into a Foo* and invoke methods on it. The
weird thing is that those methods (as long as they aren't virtual) may even
work! In Smalltalk there is no such thing, you cannot trick anyone into
interpreting a SmallInteger object as being of type Foo. It just won't work.
That said...
> As long as an object can accept the right messages, it will work,
> regardless of the context.
... your interpretation is entirely correct - if a Foo understands the set
of messages that a SmallInteger understands it will work interchangeably
with SmallIntegers. But while that may be true it still remains a Foo!
> That is, if I had a routine with two parameters, "a" and "b", and it
> expects both to be an integer:
>
> c := a plus: b
>
> If a and b happen to be strings, this code will still work. Or if they're
> ingredients to a recipe or...whatever, as long as they have a "plus"
> method.
>
> Is this true? Anyone have opinions on this? I mean, I guess it's just a
> label in the long run, but--well, I work a lot with Pascal so strong,
> static-typing, compile-time checking is the norm for me.
You are precisely right, except the "it's just a label" part. For the
advocates of static type checking the ability to coerce between types is
both a blessing and a curse. It's a blessing because without the ability
highly generic data types (like lists) are almost impossible to implement
yet, at the same time, it completely destroys the illusion that static type
checking would make your program "type-safe" in any meaningful way[*1]. In
other words, how can you possibly tell whether:
Foo *myFoo = (Foo*)list.getNext();
will answer a valid Foo or not? Even worse, how can you say whether the
coercion operation is even valid (e.g., "understood") by the element you are
retrieving from the list? Note that the meta-point here lies in
acknowledging that only the object (receiver) can really decide which
messages it (pretends to) understand. As such any "external assumption"
about the object is prone to fail and gives raise to all of the "niceties"
of the modern computer world, including buffer overruns (hey, the compiler
said it'd be okay!) etc.
[*1] Or at least I haven't seen any such meaningful interpretation. It is
true (and I won't deny it) that static types help you avoid a few mistakes
by sending objects messages that they don't understand but in reality[*2],
if that happens it means you haven't tested your code. But then at least you
know what you're up against contrary to the situation where you have a foo
cast into a Bar and wonder how it could have possibly gotten into that
state. I have debugged programs where this has happened and I take a few
DNUs every day single over that (in particular considering that I can fix
them right in the debugger ;-)
[*2] The ONE good reason for static types is auto-completion btw. This
really sucks without adequate type-information but I'm still thinking that a
decent type-inferencer could do a perfectly good job here.
Cheers,
- Andreas
More information about the Squeak-dev
mailing list
|