Frontier Software

Robert Laing's programing notes

Specification

By Robert Laing

Data Abstraction and Hierarchy

The enlightenment of seeing compound data structures as types made out of other types came to me from reading Barbara Liskov’s Data Abstraction and Hierarchy. She makes many important points about software design:

Data abstractions provide the same benefits as procedures, but for data. Recall that the main idea is to separate what an abstraction is from how it is implemented so that implementations of the same abstraction can be substituted freely.

The first step in How To Design Programs recipe is called “From Problem Analysis to Data Definitions”, which is hard to explain since it’s more art than science.

The core idea here is to focus on designing data which goes hand-in-hand with domain knowledge.

Finding your type

A lesson I learned developing an events listing site Joe Blog was that instead of reinventing the wheel, I should implement RFC 5545 (Internet Calendaring and Scheduling Core Object Specification (iCalendar)). The importance of RFCs to the modern world cannot be overstated. Without RFC 791 (IP) and RFC 793 (TCP) we’d have no internet.

Taking an example from iCalendar

BEGIN:VEVENT
SUMMARY:Abraham Lincoln
UID:c7614cff-3549-4a00-9152-d25cc1fe077d
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:TRANSPARENT
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=2;BYMONTHDAY=12
DTSTART:20080212
DTEND:20080213
DTSTAMP:20150421T141403
CATEGORIES:U.S. Presidents,Civil War People
LOCATION:Hodgenville\, Kentucky
GEO:37.5739497;-85.7399606
DESCRIPTION:Born February 12\, 1809\nSixteenth President (1861-1865)\n\n\n
 \nhttp://AmericanHistoryCalendar.com
URL:http://americanhistorycalendar.com/peoplecalendar/1,328-abraham-lincol
 n
END:VEVENT

The delimeters BEGIN:VEVENT... END:VEVENT along with a strict 80 characters-per-line cutoff are a clue that iCalendar’s ancestor vCalendar dates back to punch cards and computer keyboards with no curly brackets. A snag with iCalendar is summarised by RFC 7265 (jCal: The JSON Format for iCalendar):

…iCalendar is a specialized format that requires its own parser/generator. In contrast, JSON-based formats as defined in RFC 7159 are the native format for JavaScript widgets and libraries, and it is appropriate to have a standard form of calendar data that is easier to work with than iCalendar.

Something I find interesting is that instead of simply rewriting iCalendar key-value pairs as in {"summary": "Abraham Lincoln, ...}, the RFC uses four element arrays:

  1. the iCalendar “property” in lowercase
  2. an object to hold parameters (none of the properties in the example have parameters)
  3. type, of which 14 are defined: binary, boolean, cal-address, …
  4. value
["vevent",
  [
    ["summary", {}, "text", "Abraham Lincoln"],
    ["uid", {}, "text", "c7614cff-3549-4a00-9152-d25cc1fe077d"],
    ["sequence", {}, "integer", 0],
    ["status", {}, "text", "CONFIRMED"],
    ["transp", {}, "text", "TRANSPARENT"],
    ["rrule",
      {},
      "recur",
      {
        "freq": "YEARLY",
        "interval": 1,
        "bymonth": 2,
        "bymonthday": 12
      }
    ],
    ["dtstart", {}, "date", "2008-02-12"],
    ["dtend", {}, "date", "2008-02-13"],
    ["dtstamp", {}, "date-time", "2015-04-21T14:14:03Z"],
    ["categories", {}, "text", "U.S. Presidents,Civil War People"],
    ["location", {}, "text", "Hodgenville\\, Kentucky"],
    ["geo", {}, "float", [37.5739497, -85.7399606]],
    ["description", {}, "text", "Born February 12\\, 1809\nSixteenth President (1861-1865)\n\n\n\nhttp://AmericanHistoryCalendar.com"],
    ["url", {}, "text", "http://americanhistorycalendar.com/peoplecalendar/1,328-abraham-lincoln"]
  ]
]

A vevent (whether in iCalendar or jCalendar) is an element in a list, which in iCalendar is bounded by BEGIN:VCALENDAR... END:VCALENDAR and in jCalendar by ["vcalendar", ...], and other types of elements this list could house are vtodo, vjournal, vfreebusy, vtimezone, and valarm.

As with just about every application, the iCalendar data format boils down to a list of key-value pairs. How to assign values to keys — key = value, key: value, key := value, {key, value}, key(value), (define key value)… and then whether that value should be allowed to change pretty much sums up the only differences between programming languages.

The list housing these various objects is often called the state, and a listening loop which updates the state as it receives messages is the basic structure of video games and many other applications.

Schemas

What to call keys isn’t arbitrary. A lot of coding today — especially tweeking a document generation system like Hugo — is learning in what text file which key is set, and what the different values it can be set to are, and what changes these make.

Names of keys are called schemas, and for events the reference site is shema.org — which uses completely different names:

{
  "@context": "https://schema.org",
  "@type": "Event",
  "location": {
    "@type": "Place",
    "address": {
      "@type": "PostalAddress",
      "addressLocality": "Denver",
      "addressRegion": "CO",
      "postalCode": "80209",
      "streetAddress": "7 S. Broadway"
    },
    "name": "The Hi-Dive"
  },
  "name": "Typhoon with Radiation City",
  "offers": {
    "@type": "Offer",
    "price": "13.00",
    "priceCurrency": "USD",
    "url": "http://www.ticketfly.com/purchase/309433"
  },
  "startDate": "2013-09-14T21:30"
}

Before the Cambridge Analytica scandal, I used to be able to use Facebook’s GraphQL service to get events in Json using neither jCalendar’s nor schema.org’s conventions. Subsequent to getting bust for selling user data to evil marketing companies, Facebook made its GraphQL service useless for venues and artists wanting to promote their gigs.

[
    {
        "description": "We would be honoured to have your presence at our unholy matrimony. Come share in our joy and love as we exchange vows and get wrecked
.",
        "end_time": "2017-04-29T01:00:00+0200",
        "id": "421476341554764",
        "name": "Cortina Whiplash 'WE DO' - Album Launch",
        "place": {
            "id": "487944488039333",
            "location": {
                "city": "Johannesburg",
                "country": "South Africa",
                "latitude": -26.207930103884,
                "longitude": 28.031809329987,
                "street": "1 Fox Street, Ferreirastown",
                "zip": "2000"
            },
            "name": "The Good Luck Bar"
        },
        "rsvp_status": "attending",
        "start_time": "2017-04-28T19:00:00+0200"
    },
...
]

Researching the domain of the application will hopefully lead to the overarching type we are dealing with, hopefully one defined by an open standard such as RFC or schema.org. Given corporate antipathy to open standards, needing to then filter and translate supplied data to what the application is designed to consume is an inevitable layer in the design.

Last updated on 1 Jan 2021
Published on 1 Jan 2021

Content Footer