One of the nicer things about Smalltalk is the consistency of
the object model. A fair amount of that is due to the fact that
everything is an object, and that dynamic typing allows for
developers to just "do what works". I have a pretty simple example
of this - let's look at the method #factorial
result := 10 factorial.
result inspect.
That gives us:
Ok, that doesn't seem exciting - we ended up with a SmallInteger object. However, now let's try this one:
result := 100 factorial.
result inspect
The nice thing here is that we didn't have to do anything special - in the process of getting the answer to the second question, the SmallInteger object got promoted up to a LargePositiveInteger, and I didn't need to do anything - no setting up of interfaces, no casting, no need to ensure that all factorials produce LargePositiveInteger objects - they get created when they are needed. Developers can do that themselves, btw - the library does this kind of thing with numbers, you can do similar things with your own objects as needed.
The bottom line - Smalltalk stays out of your way, and lets you solve the problem at hand. Instead of having the satisfy the anal retentive needs of the compiler.