The other day, I pushed up a post on the simplicity and power of Smalltalk, using the #factorial method in class SmallInteger as an example. Here's the entire implementation within the superclass, Integer:
factorial
| tmp |
self < 0
ifTrue: [^self class
raise: #domainErrorSignal
receiver: self
selector: #factorial
errorString: (#errFactorialInvalid <<
#dialogs >> 'Factorial is invalid on negative numbers')].
tmp := 1.
2 to: self do: [:i | tmp := tmp * i].
^tmp
So ignoring the error handling, the basic code is 3 lines. In one place. Sure, it relies on the ability of SmallInteger objects to auto-promote themselves - but the point is, as a developer, I don't need to worry about those details - it just works, and gives me the right answer. I also made the point that developers can create code that has the same kind of power - a quick look at #become: will explain what I mean. It's not a method to be used lightly, but - when you need it, it's invaluable.
If I wanted to write #factorial in Java, would I be able to write one method in one place? Would the issues of correct type get in the way, and force me to consider utterly irrelevant implementation details? That was the point I was making. The fewer "make the compiler happy" issues I need to deal with, the better off I am. At the end of the day, the compiler isn't my customer.