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.
sender column (String)
recipients column (List<String>)
day column (String)
Handling time was more interesting though. Ideas here include:
a single number with decimals for hours
a single numbers of minutes since midnight
a 4-digit number that uses 24-hour time like 1830
a string like "4:25 pm"
two columns, one for hour and one for minutes
a column with a list of two numbers (hour and min)
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,
TimeData is a new _type_ name (akin to String, Boolean, etc)
time is a function that creates TimeData values. Such functions that build data are called constructors.
hours and mins are names of the parts of a piece of time data.
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 |