What is a Data Concept?
A data concept describes a kind of data that exists in a program or application and would be visible to an end user. Examples of data concepts in a course-registration system, for example, would include: Course, Time Slot, Catalog, Schedule, and Shopping Cart.
Note: Our notion of data concepts is inspired by Daniel Jackson's notion of software concepts, as explained in his book The Essence of Software. Our data concepts are oriented towards beginning programmers: they are more abstract than data types or data structures, but more concrete than Jackson's concepts by virtue of being tied to specific applications. We envision slowly showing students how to abstract over data concepts to arrive at something closer to Jackson's concepts.
Example of a Data Concept: Catalog
There are five components to a concept (plus a sixth that get expressed separately). Here is a complete example for the Catalog in the registration system. The text below the code explains each part.
concept Catalog [Entry]
purpose provide access to a collection of entries, perhaps filtered
by descriptive labels
scenario someone searches the catalog to find entries that meet
certain criteria
state entries : Set(Entry)
labels : Map(Label, Set(Entry)) # a label is a string
actions
add : (Catalog, Entry) -> Catalog
result: a state in which the entry is in the catalog,
under no labels
remove : (Catalog, Entry) -> Catalog
pre-req: the entry is in the catalog
result: a state in which the entry is gone, and appears
under no label
tag : (Catalog, Entry, Label) -> Catalog
pre-req: the entry is in the catalog
result: a state in which the entry appears under that label
untag : (Catalog, Entry, Label) -> Catalog
pre-req: the entry appears under that label
result: a state in which it no longer does
queries
find : (Catalog, Label) -> Set(Entry)
labelsOf : (Catalog, Entry) -> Set(Label)
Name and type parameters
Each concept has a name followed (in brackets) by the names of types used in the concept. A concept can't assume anything about the named types, other than that they exist. Catalog works the same way whether an Entry is a course, a book, or a recipe; the registration system fills Entry in with Course.
Purpose
One sentence, stating what the concept provides. A good purpose is:
- user-focused — it describes a benefit to the user, not how the internal program works;
- evaluable — you could look at a design and argue about whether it achieves it.
Core Scenario
A short archetypal scenario, in the form if you do this and this, then that happens, showing the concept delivering on its purpose. It is not a complete description of the behavior — it's the defining story, the thing you'd tell someone who asked "so what's the point?"
State
What the concept has to remember, described with types. Keep it minimal: include only what the actions and queries below actually need.
Why does a Catalog need entries as well as labels?
entries earns its place because an entry can carry no labels. Without it, a course just added to the catalog would not be in the catalog until someone tagged it, which is not what a user means by adding a course.
Actions and Queries
Actions summarize the ways the state can change, written as functions from a state to a
new state. This is the same idea we've seen with reactors and functions like on-tick: an action takes the current state (plus whatever arguments it needs) and returns the next state. An action that only reads the state and returns an answer is called a query: find and labelsOf don't change anything, but they summarize questions we might ask of a Catalog.
Some actions only make sense in some states. For example, you can't remove a course from the catalog that was never in it. The pre-req(uisite) line of the action describes when it can be used.
Constraints
A constraint is a condition that has to hold in every state. The state says what the concept can remember; the constraints say which of those states actually make sense. Often, constraints are about a single state, such as "no course appears twice in the catalog". Actions are responsible for maintaining the constraints. Sometimes, constraints are phrased as relationships between the states before and after an action. Here's an example of each:
- Every entry appearing under a label in
labelsis also inentries— nothing is tagged that isn't in the catalog. - An
addaction results in the number ofentriesincreasing by one.
Constraints across concepts
Combining concepts in an application can yield additional constraints that discuss multiple concepts. The registration system also has a Cart, holding the courses a student is considering. Putting it beside Catalog gives us:
- Every course in a Cart is an entry in the Catalog — a student cannot be shopping for a course the university does not offer.
- Once a course is removed from the Catalog, it appears in no
student's Cart. Neither concept can arrange this on its own: the
application has to call
Cart.removefor each affected student when it callsCatalog.remove.