No Source Code
One somewhat unusual feature of Smalltalk was that it didn't include an idea of source code. In a traditional programming environment, you have source code, which is a textual representation of a program. This source code is transformed by a compiler into object code, which can be executed by the machine.
In Smalltalk, there was no such model. You wrote Smalltalk programs by sending messages to objects. For example, to create a new class, you sent a #subclass: message to an existing class. You then sent more messages to the resulting class to add instance variables and methods.
The development environment was entirely interactive. Everything that you could see on the screen was an object, which could be inspected and modified by sending it messages. This made Smalltalk a really great environment for teaching programming—the novice programmer could inspect everything.
Of course, sometimes you want to modify an object in a way other than adding to it; for example, you might want to modify what a method does. You could do this in Smalltalk by defining a new method, but that approach would be somewhat cumbersome for every small change. That's where introspection came in. Every Smalltalk object could tell you about itself, in several ways. One way was to provide a textual representation of individual methods. Then you could modify this representation and re-create a method from it.
Smalltalk code was distributed in images, which were snapshots of a running Smalltalk virtual machine. You simply loaded the image into a virtual machine and started it running—making development incredibly easy.
Smalltalk's development system had a lot of features in 1980 that are only just starting to make their way into mainstream integrated development environments. Automatic refactoring tools are a good example. Amusingly, you'll often hear people defending strongly typed languages by saying that these tools require type annotations—ignoring the fact that Smalltalk had them 30 years ago.