Skip to content

zz note: traversing dynamic type spaces

David Jeske edited this page Jun 19, 2019 · 6 revisions

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);
  }
}