Exercise 2: Understanding Concepts
Overview
- Purpose. The purpose of this problem set is to give you practice in reading and writing concepts, so you will be able to use concepts confidently in your design work.
- Collaboration. In contrast to your project work, we request that you do not collaborate on this assignment so that you learn the ideas well, and we encourage you to do the problems without using an LLM. But be sure to ask for help from the staff if you get stuck!
Exercise 1: Reading a concept
To help you understand some of the subtleties in concept design (and how seemingly small concept design decisions can have major implications for users), this exercise asks you to read a mostly complete concept and answer some questions about it.
The concept is GiftRegistering, which is widely used for wedding and other gifts. Many department stores offer gift registering; so do online stores such as Amazon; and there are specialized services (such as Zola). The idea in short is that someone (typically celebrating some occasion like a wedding or birthday) creates a shopping list of items they would like to receive. Their friends can then see which items are on the list, and purchase them for them. Here is the concept definition:
concept GiftRegistering [User, Item]
purpose track purchases of requested gifts; prevent people buying you things you don't want
principle
a recipient creates a registry, and adds items to it indicating the number of each requested;
opens the registry so it becomes publicly visible;
then givers can view which items are still available and purchase them;
and finally the recipient closes the registry, after which it is no longer publicly visible
but the recipient can see which items were purchased and by whom.
state
a set of Registries with
an owner User
an active Flag
a set of Requests
a set of Requests with
an Item
a count Number
a set of Purchases
a set of Purchases with
a purchaser User
an Item
a count Number
actions
create (owner: User) : return (registry: Registry)
then create a new registry with this owner, active set to false and no requests, and return it
addItem (registry: Registry, item: Item, count: Number)
where registry exists and count is greater than zero
then if a request for this item exists in this registry, add the given count to its count
otherwise create a new request for the item with this count and no purchases, and add it to the registry
removeItem (registry: Registry, item: Item)
where a request for this item exists in the registry
then remove the request from the registry and delete the request
open (registry: Registry)
where registry exists and is not active
then make registry active
close (registry: Registry)
where registry exists and is active
then make registry not active
purchase (purchaser: User, registry: Registry, item: Item, count: Number)
where registry exists and is active, count is greater than zero, and the registry has a request for this item with a count no less than the given count plus the sum of the counts of purchases for that request
then create a new purchase for this purchaser, item and count, and add it to that request's purchases
Questions
- Invariants. What are two intended invariants of the state? (Hint: one is about aggregation/counts of items, and one relates requests and purchases; ignore the obvious invariant that counts must be greater than zero). Say which one is more important and why; identify the action whose design is most affected by it, and say how it preserves it.
- Fixing an action. Can you identify an action that fails to preserve one of these intended invariants, and give a sequence of actions showing how this happens? How might this problem be fixed?
- Inferring behavior. The operational principle describes the typical scenario in which the registry is opened and eventually closed. But a concept specification often allows other scenarios. By reading the specs of the concept actions, say whether a registry can be opened and closed repeatedly. What is a reason to allow this?
- Registry deletion. There is no action to delete a registry. What are some reasons to add one, or not to?
- Queries. What are two common queries likely to be executed against the concept state? (Hint: one is executed by a registry owner, and one by a giver of a gift.)
- Hiding purchases. A common feature of gift registries is to allow the recipient to choose not to see purchases so that an element of surprise is retained. How would you augment the concept specification to support this?
- External types. The User and Item types are external types, specified as generic parameters of the concept. The Item type might be populated by SKU codes, for example. Explain why this is preferable to representing items with their names, descriptions, prices, etc.
Deliverables: Succinct answers to each of the questions.
Exercise 2: Extending a familiar concept
In this exercise, you'll complete the description of a familiar concept: authentication of users with passwords. You'll also use this concept specification in the next exercise.
concept PasswordAuthenticating
purpose identify users; prevent one user from masquerading as another
principle after a user registers with a username and a password,
they can authenticate with that same username and password
and be treated each time as the same user
state
a set of Users with ...
actions
register (username: String, password: String) : return (user: User)
...
authenticate (username: String, password: String) : return (user: User)
...
Questions
- Complete the definition of the concept state.
- Write a where/then specification for each of the two actions. (Hints: The register action creates and returns a new user. The authenticate action is primarily a guard, and doesn't mutate the state.)
- What essential invariant must hold on the state? How is it preserved?
- One widely used extension of this concept requires that registration be confirmed by email. Extend the concept to include this functionality. (Hints: you should add (1) an extra result variable to the register action that returns a secret token (that, via a reaction, will be emailed to the user); (2) a new confirm action that completes the registration; (3) whatever additional state is needed to support this behavior.)
Deliverables: Succinct answers to each of the questions with the required additional specification fragments.
Exercise 3: Comparing concepts
One way to improve your understanding of concept design is to compare related concepts, and try to determine (and then articulate) how and why they differ. Confusion between related concepts can be a design flaw in itself, when the designer fails to convey (through the user interface and support materials) what concept is being offered in a particular situation.
For example, X/Twitter used to have a feature called "favorites," but it wasn't clear if this was an instance of an Upvoting concept (which collected votes from users for popularity ranking) or a Favoriting (or Bookmarking) concept (which let users save favorite tweets). In 2015, Twitter renamed "favorites" to "likes" and replaced the yellow star icon with a red heart, explaining in a press release "We are changing our star icon for favorites to a heart and we’ll be calling them likes… We know that at times the star could be confusing, especially to newcomers. You might like a lot of things, but not everything can be your favorite." Needless to say, this didn't help explain what concept was actually at play, and in 2017, Melania Trump famously "liked" a tweet that taunted her husband, presumably believing that she was bookmarking it, when in fact her "like" was shown publicly as a gesture of approval. In 2018, Twitter finally added a Bookmark concept.
In this case, it seems possible that the confusion was intentional, since public likes, unlike private bookmarks, serve the company's business goals of increasing visible user engagement (and indeed, even after they were added, the bookmarking actions were buried in the user interface and far harder to access than the upvoting actions). In other cases, confusion between concepts is simply a consequence of poor design, and even with good design it is not possible to ensure complete clarity for all users given their diversity of background and assumptions.
Passwords vs. Personal Access Tokens
GitHub offers a form of authentication called personal access tokens. This is described as "an alternative to using passwords." Creating a token sounds very much like creating a password with a strong password helper: you click a button to create a token, and get an obscure string which you can then save. Using a token appears to be the same as using a password: you enter a username and the token string, and will then be authenticated if the string matches the one that was generated when the token was created. Moreover, at the very start of the article we are told "Treat your access tokens like passwords."
So what exactly is the difference between the standard PasswordAuthenticating concept and the PersonalAccessTokening concept? Skim the GitHub page, extracting (and reading carefully) the relevant parts, and write a minimal specification of the PersonalAccessTokening concept, paying particular attention to the purposes and operational principle, and say how it differs from PasswordAuthenticating. Finally, make a suggestion for how GitHub could make the explanation of personal access tokens easier to grasp.
Note: The Github page actually describes two different kinds of tokens: "classic" and "fine-grained". You should consider only the classic kind, which is the kind that is closer to passwords. (The fine-grained tokens are different from passwords in a more obvious way, because they limit access to particular assets owned by a user.)
Deliverables: a concept specification for PersonalAccessTokening and a succinct note about how it differs from PasswordAuthenticating and a change you might make to the GitHub documentation to explain this.
Hint: this is not easy, because the behavior of the two concepts is superficially similar. But the differences in purpose and operational principle are very significant. If you haven't got to the point that you could explain the difference in 3 minutes to a friend who isn't a software expert, you haven't understood it yet.
Exercise 4: Defining familiar Concepts
Concepts can be designed and understood entirely independently of one another, even if eventually they will be composed with other concepts in a larger application context. Designing and evaluating individual concepts is thus an important skill.
In this exercise, you'll define concepts for some examples that you're probably familiar with. For each one, you should provide all the standard elements of a concept (name, purpose, operational principle, type declarations, state and actions), and explain any subtleties of your definition in a brief notes section at the end.
URL Shortening
Define a concept for the essential function of a URL shortening service such as tinyurl.com or bit.ly. Your concept should support both user-defined and autogenerated URL suffixes.
Shopping Cart
Define a concept for the shopping cart of an online store. Include only the shopping behavior itself, and not the all the other functions that an online store typically supports with other concepts (such as searching and paying). Even ordering is a distinct concept, and you can assume that when the checkout action occurs in the shopping cart concept, a corresponding order is created in the ordering concept (by a reaction that you do not need to specify).
Time-Based One-Time Password (TOTP)
Multifactor authentication schemes improve on simple password-only schemes. One common scheme uses an app that runs on the user's phone (or computer) that generates time-based tokens that are then entered by the user as part of the authentication process. Define a concept for this scheme.
Hints: TOTP is not the same as the scheme in which a token is sent by email or text message; an important property of TOTP is that there is no need to send any token to the user at authentication time. You can find an algorithmic outline of TOTP on Wikipedia, but note that you should not include in your concept any cryptographic details, but can just assume the existence of a cryptographic function that you can refer to in your concept specification. The state of your concept should include both state that belongs on the server and state that belongs in users' client machines; make clear in your concept definition where each component of the state belongs.
Deliverables: three concept specifications, with any subtleties explained in brief additional notes.
Advice
- Concept guides. Defining a concept explains how to develop a concept definition. Use Specifying a concept for the detailed notation and Specifying concept state for state declarations.
- Be succinct. The concept notation is pretty minimal, so try and keep your concept specifications short and to the point. Include only the essential actions. Any additional commentary that you might want to include should be in a notes section at the end of the concept specification.