-
Notifications
You must be signed in to change notification settings - Fork 17
zz note: traversing dynamic type spaces
Looking at zz note: important dynamic programming patterns, one important pattern is traversing dynamic type spaces.
By this we mean, allow traversal of foreign parsed data using simple native-looking syntax.
Consider the following XML document...
<customer name="David" Phone="555.1212"/>
<customer name="Fred" Phone="555"1313"/>
<customer name="Suzy" Phone="555.1414>
<order id=5223 date=... />
</customer>
Using something like the Python meta-object protocol, accessing data in this tree can be as simple as:
for customer in dom._all("customer"):
print "Name: " + customer.name
for orders in customer._all("order"):
print " Order:" + orders.id
However, in a typical static typed DOM API, this typically turns into a morass of quoted strings and function calls. For example, using the C# XmlDocument, one way to write this code is below.
foreach(var node in dom.GetElementsByTagName("customer")) {
System.println("Name: " ..
node.Attributes.ToDictionary(p => p.Name.toLower())["name"].Value);
foreach(var orders in node.GetElementsByTagName("order")) {
System.println(" Order:" ..
orders.Attributes.ToDictionary(p => p.Name.toLower())["id"].Value);
}
}
Note that we are not getting any static safety over the DOM contents using this larger code. It's just more confusing and more keystrokes.
C# / CLR also has a type of dynamic object with a Python-like runtime meta-object protocol. Using these objects, we can express this DOM traversal in the same way Python can:
foreach(dynamic customer in dom._all("customer")) {
System.println("Name: " .. customer.name);
foreach(dynamic order in customer._all("order")) {
System.println(" Order: " .. order.id);
}
}