Skip to content

zz node: heterogeneous lists of maps

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

One element of idiomatic dynamic programming which is cumbersome to translate to irken is lists of heterogeneous maps, maps which vary in both key-structure and value type. Consider the Python data-structure:

data = [ { "a": 1, "b" : "one", "extra": "data"},
         { "a": 2, "b" : "two"} ]

In Python, we can write code which processes this list, optionally handling the "extra" data if it is present. This is particularly common when loading datasets which vary over time, where not all versions of the records contain all fields.

In Irken, records are key/value data structures which allow different types of values. This allows compile time static checking of all the record fields. For example, if we drop the "extra" data, we can represent this as:

(define data (list { a = 1 b = "one" }
                   { a = 2 b = "two" }))

Alternatively, Irken maps (currently called tree) are a data-structure supporting dynamic sets of keys, but a single map must have values of the same type. In order to store the above example in a map, we both lose static type-checking for the key-space, and the variant types become cumbersome:

(define data (list (tree/make ("a" (:int 1)) ("b" (:str "one")) ("extra" (:str "data")))
                   (tree/make ("a" (:int 2)) ("b" (:str "two"))) ))

Solutions ?

Typescript has some nice support for interfaces with optional fields. In Typescript, the above type can be declared as:

interface ListElement {
   a : number;
   b : string;
   extra? : string;
}

This provides static type-checking for field names, in the sense that referencing a mis-spelled field which is never present is a compiler error. However, it also allows fields to be optional.

See... zz note: row optional polymorphic records