Rich and Travis have already been discussing declarations and reflection. This post is not as much a user's guide as an explanation why the current incarnation of the framework doesn't commit very much to that idea. I can say right away that I am not brimming with excitement regarding declarations. Nor am I rejecting the idea outright.
I'll start with some definitions and clarifications so we don't entangle ourselves in our own misinterpretations.
One thing we talk about is reflection. Loosely speaking, reflection is the ability of our Smalltalk image to know and/or modify its structure. In our neck of the woods, reflection is universally considered to be a Very Good Thing.
The other thing are declarations. One motif that rather bothered me in the discussion was the apparent confusion between declarations and reflection, with an implication that declarations are needed because they provide reflection and reflection is good. Declarations and reflection are entirely different things. You can have one and not the other. Declarations can support reflection, but they are neither required nor automatically enable it. Consider that C++ and similar languages are very declaration-heavy and reflection-light, while Smalltalk is the other way around.
We can fairly accurately find out what messages methods of a particular class send without having the class declare each message it sends. What we find is not guaranteed to be 100% accurate, but for most tasks in tools 90% is good enough. Enough to say that requiring mandatory declarations of all sent messages so the tools could gain the last 10% is not a very attractive proposition, at least not within our laid-back Smalltalk culture.
To avoid confusion, it's better to separate reflection into two kinds: introspective reflection, when you muck around with code and figure out what it does, and declarative reflection when you know what the code does because declaration restricts what it could do. (Yes, I've just made these terms up).
The important difference between these is that introspective reflection follows the code while declarations want the code to follow them. This once again shows why reflection and declarations are not the same. The primary goal of a declaration is limiting what is possible in the code, and reflection is only a byproduct of that. In fact, declarative reflection is not true reflection at all--you know your code won't do what declaration does not allow, but you don't know how much it does of what is allowed. You still need introspective reflection to know that.
Declarations establish a law for code to follow, and there is no law without law enforcement. Unless you ensure the code only does what the declarations say, any "reflection" based on the declarations is only an educated guess. So, reflection might not go hand-in-hand with declarations, but enforcement does.
Enforcement can be done at compile time and runtime. Compile-time enforcement is far superior. It's more user-friendly because it points our errors as soon as they are made. It's also more reliable because it catches all errors, while runtime errors can go unnoticed if the particular piece of code runs rarely. This is why even for message sends, the sent selector is verified to at least exist at compile time, with a warning if it doesn't.
With all the above combined, I think I know what Travis meant when he said about using introspective reflection for finding announcements, "This seemed like a cool idea, because, it's so... I don't know what the right word is." It's so much more in the spirit of Smalltalk to let the code be free and follow it when needed, rather than establish artificial limits at a high level, with whatever good intentions. Consider how the existing declarations (such as variable, import, pragma) restrict the code only in the most basic ground rules, usually enforced at compile time.
This is why I am not too keen on embracing announcement declarations outright. They feel alien. They are too high up the food chain. Consider the parallel with Exceptions. There are no declarations of exceptions a class can signal. Do we need them? I'm sure someone could come up with a reason for that. Are we doing well without them? There's the rub.
If Exceptions are not a good example as far as declarations are concerned, what about #eventsTriggered in triggerEvent? Here is why eventsTriggered are apparently intended to solve an unrelated problem, which Announcements solve much better by different means.
Let's start with this. Assuming a class has a declaration of announced things of some sort, enforced at runtime, when exactly should it be enforced? The #announce: method is one obvious spot, since otherwise we could announce things we claim we don't announce. What about when accepting subscriptions--should it be ok to subscribe to something an object can't announce? In other words, what precisely does an announcement declaration restrict: only announcements, or both announcements and subscriptions?
Regardless of the answer, what triggerEvent provides is off the mark. It has something called event checking, turned off by default in Object. A subclass can turn it on and add #eventsTriggered declarations. However, a closer look reveals that what is checked against those declarations are actually the "when:..." subscription messages, while triggerEvent: won't balk at anything. So, despite the "eventsTriggered" name, instances can trigger anything at all--it's just that they won't accept subscriptions to it!
Obviously, event checking in triggerEvent isn't concerned with any high-level principles like "declarations should limit and describe what the code can do". It must have been implemented ad-hoc to address some immediate practical needs. And I think the main of those was protecting against typos. When events are symbols, it's easy to mistype one, subscribe to an unexistent event and then wonder why the event is apparently not being triggered. So the true purpose of #eventsTriggered, despite the name, is not to list the events a class triggers, but simply list some symbols the class knows are valid event names it presumably triggers.
Now, to Announcements.
If the true purpose of #eventsTriggered appears to be protection against typos, Announcements have it. Only better. If you mistype an announcement name you get an error at compile time, and the error checker can event find the correct name for you.
With this out of the way and the counter-example of Exceptions, I hope it's getting clear why I am not entirely convinced declarations are the way to go. I believe we simply don't have enough collective experience using them to come to any conclusions right now. Now is the time to let a hundred flowers bloom to get that experience, and not expect an answer in a month--and probably not in a year.
This is why all the Announcements proper provides is a hook for runtime enforcement of both subscriptions and announcements. All announcements and all subscription requests need to pass a class check implemented by #mayAnnounce: method of the announcer. The method accepts the class being announced or subscribed to as the argument and should answer false if the class is not supported.
However, there is no "official" way in Object of declaring the supported announcements, and the default implementation of #mayAnnounce: in Object answers true to everything.
Having said this, I published to the public repository System-Announcements-Extras package with Announcer class implementing announcement declarations--as an example or a superclass to subsclass from for those willing to experiment. As I said, I don't reject the idea outright.
This is the lay of the land for the near future.