Class summary:   Introduction to Datatypes
1 A Data-Design Exercise
2 User-Defined Datatypes

Class summary: Introduction to Datatypes

Copyright (c) 2017 Kathi Fisler

1 A Data-Design Exercise

Imagine that you are writing an email system, and want to be able to study usage patterns over the course of a week. You don’t want to study contents of messages (for privacy sake), so you’ll just need to store the so-called "meta-data" (the "who and when" information).

Specifically, each email has a sender, one or more recipients, the day of the week that it was sent ("Mon", etc), and the time (hours and mins) that it was sent. What combination of lists and tables would you create to hold this data?

After discussion, students generally agreed that this needed a table. A list-of-lists would also have worked, though the table makes it easier to extract individual columns. The table also makes it easier to spot missing entries.

Let’s go with a table. Pretty much all proposals included the following three columns:
  • sender column (String)

  • recipients column (List<String>)

  • day column (String)

Handling time was more interesting though. Ideas here include:

Separating hours from mins seems useful if we have to do any numeric computations on the times (sorting, for example). The two-columns version is nice because we can access the time components by name. The list version is nice because it treats time as a single, cohesive piece of data. Which to choose?

You don’t have to choose. You just need a new concept – creating your own datatypes!

2 User-Defined Datatypes

Pyret (indeed, most languages) give you a way to define your own types of data. Here, we will define a new type called TimeData, where a value of this type has two components – hours and mins (we’re assuming 24-hour time).

  data TimeData:

    | time(hours :: Number, mins :: Number)

  end

Here,

Here are examples of creating TimeData values:

  noon = time(12, 0)

  5pm = time(19, 0)

  

  messages =

    table: sender :: String, recipients :: List<String>,

      day :: String, time :: TimeData

      row: "kathi", [list: "eli"], "Monday", time(8, 30)

  end

Finally, here’s a function that computes over TimeData – we can use the . notation and the name of a component to get out a piece of the data value.

  fun before-noon(t : TimeData) -> Boolean:

    doc: "is this time before noon"

    t.hours < 12

  where:

    before-noon(noon) is false

    before-noon(5pm) is false

    before-noon(11, 59) is true

  end