Yesterday, douglasp blogged about his Smalltalk RSS reader. What is particularly neat is the way he appears to handle XML (more details forthcoming, I’m filling in the blanks here). Usually an XML parser will slurp in your document and then allow you to do calls like document->GetField(“title”). Now here’s where Smalltalk kicks in to solve two problems.
Problem #1 is that it’s quite clunky to have to call the “GetField” method when actually what you’re doing is accessing some data in the object. It’d be nicer if we could just call document.title.
Following from that, problem #2 is that we might make a mistake and ask for “titel” by accident. What happens then?
Smalltalk allows you to build new types at runtime and the instantiate them. This means that our XML reader can figure out the structure of the XML document (or read the DTD) and the build a new type for it. You can’t just access the data “in an object-like manner” – it really is a first class object. If there’s a “title” tag in the document, our object can have a “title” accessor so that we can just say document.title. These aren’t “fake” objects or types in any way. They are 100% pure smalltalk objects and types which your program decided to build. After all, any class which you create using the System Browser appeared in a similiar puff of smoke into the smalltalk world. Your XML reader class can build new types just as well as the System Browser can. That’s one of the great things about Smalltalk – no part of the system has “magic power”. If the debugger can do something, you can do it in your code. If the Browser can create new classes, you can do it in your code too.
This XML parsing technique only possible because Smalltalk is run-time typed. Clearly, you can’t assign a static type to XMLReader.Parse() call if it only invents the return type at runtime.
This also leads to an elegant solution for problem #2. If you mistype “titel” then you will get the standard smalltalk “don’t understand message” error and you can then drop into the debugger and sort your problem out. You don’t need to remember any special rules like “GetField() return NULL if the field doesn’t exist”. It’s all just vanilla smalltalk, and everything works like you’d expect.
Today is a “yay, dynamic languages” day.