Creating the Name ADT

On this page, you will develop an Abstract Data Type to store and access name data (first-name, last-name, etc.).

Jasmine: Right now, our program uses one text string to hold each contact's name, but people have multiple names.
Omar: We can just put both names in together.
Jasmine: Let's look at the list on your phone.
list of names
Ah, they're sorted by last name, even though it's not the beginning of the name text.
Omar: Hmmm... What if we used another list to separate the last name from the first name?
Jasmine: OK. So, we could make a name ADT and two new selectors: one to report the name they way it appears for the user: first-name last-name; and one to report the name so we can sort it: last-name comma first-name.
  1. If it isn't open already, open your U3L1-ContactList project.
  2. Develop a name constructor. It should accept a first name and last name as input and report the whole name as a list:
    name, first: (Barack) last: (Obama) reporting {Barack, Obama}
  3. Create two new selectors to distinguish between the two orders by using join. Test them with your name constructor.
    display-form from name: (name, first (Barack) Last: (Obama)) reporting {Barack Obama}
    sorting-form from name: (name, first (Barack) Last: (Obama)) reporting {Obama, Barack}
  4. Give the selectors expected input types to make it obvious that they each expect a list (one whole name) as input.
  5. Analyze and Debug. Jasmine and Omar tried to use their sorting form of name block together with their contact constructor. They were expecting their code to report "Anderson, Jasmine", but it didn't work.
    sorting-form from name: (contact name: (Betsy) address: (123 Main St. #4, New York, NY 10001) phone: (212-555-1234)) reporting 123 Main St. #4, New York, NY 10001 Betsy Anderson
    Talk with Your Partner What's going wrong? What could they do instead?
  6. Make the name input slot of your contact constructor expect a list item, as shown here:
    contact name: () address: () phone: ()
  7. Clear your list (reset it to an empty list), and add a few contacts using the name constructor.
    contact name: (name, first: (Betsy) last: (Anderson)) address: (123 Main St. #4, New York, NY 10001) phone: (212-555-1234)
  8. Debug any problems. The contacts in your contact list should each have a list as the first name, like this:
    Save your work contact list watcher in list view showing contact with name as list
contact list with one contact showing: {{Betsy, Anderson}, {123 Main St. #4, New York, NY, 10001}, 212-555-1234}
  1. Develop an abstract data type (ADT) to store and access address data.
    1. Create an ADT to manage four pieces of data for each address: street address, city, state, and zip. You will need:
      • One address constructor
      • Four selectors: street address from address, city from address, state from address, and zip from address.
    2. Make the address input slot of your contact constructor expect a list.
    3. Clear your list, add several contacts using your name and address constructors, and try selecting specific data (such as the city) from a contact.
    4. Debug any problems.
Save your work
Tough Stuff but worth it!
Mei and Morgan join the conversation about Contact List
Mei: Do you want your app to work in China? People there put their family name first, so Sun Yìxiān is in the Sun family, and would be in the S part of your name list, not the Y part.
Morgan: So, you're saying we need two different name types, with different constructors and selectors?
Omar: At least two. After you finish your program, I'll tell you about names in Iceland (given name first, but sorted on given name, not family name) and Myanmar (no family name at all)!
Morgan puts his head in his hands and groans.
Jasmine: Nah, it doesn't have to be that bad. We'll just have one name type, but it'll have variants, and we'll include a type tag along with the given and family parts to indicate given-first (as in the US) or family-first (as in China). Omar can add more variants later if he wants.
  1. Make this block:
    name, type: ( ) given: ( ) family: ( ):  report (list type given family)
  2. There are only two allowable values for the type input, and you won't want users of your program to have to remember them and type them in without spelling errors. Instead, you want a menu input, like this:
    name block with menu input slot for type

    Adding Menu Inputs

    1. Edit the name block, and click on the orange type variable in its hat block.
    2. Click on the right-pointing triangle to open the input type selector.
    3. Right-click on the background, and select "options..."
      option context menu in input dialog
    4. Enter the type tags in the box, one per line:
      menu options 'given-first' and 'family-first'
    5. Click OK, then right-click the type selector again and choose "read-only."
      There are two kinds of menu input slots:
      touching (...) ?  read-only input slot
      item (...) non-read-only menu input slot
      For this block, we don't want users to enter values other than the ones in the menu.
    6. Click OK on the type input box and then on the Block Editor.
Morgan: Okay, now I guess we have to make selectors, right?
name type (name): report item 1 of (name) given name (name): report item 2 of (name) family name (name):  report item 3 (name)
Omar: Don't call the first one type from name. We're going to need the same type selector for other ADTs also, so call it type tag.
Morgan: How do you know?
Omar: I read ahead in the curriculum!
Morgan and Jasmine groan.
  1. Make the three selectors, using Omar's suggested name for the first one.
  2. family from name: (name, type: given-first given: Abraham family: Lincoln)  -->  Lincoln
Morgan: But I'm not sure how this variant idea is going to help. Mostly, the rest of the program isn't going to want the family name alone. It's going to want the entire name, either in display order or in sorting order, so aren't we going to need blocks like given first name in sorted form (name) and so on?
Jasmine: Oh, hang on, you're thinking of it as a selector just for one variant (given-first names), but we can simplify a bit by thinking of it as a selector for all names, name (sorted form) ( ). The definition is a little more complicated, but the rest of the program will be able to use it without caring what kind of variant it has.
  1. For a given-first name we put a comma and space between the names, "Anderson, Jasmine"; there won't be a comma for family-first names ("Sun Yìxiān").
    This is confusing because they already have a block with this name. Are they supposed to rebuild it here? We should be clearer. Also, I just don't understand this. I'm sorry. I tried to build solutions for this project, but I'm stuck here. I don't understand what goes next in this block, and I don't think we should keep something in the curriculum that I can't even understand what we are trying to build, but you know that and you want it anyway... --MF, 7/13/17
    Finish this definition:
    name (sorted form) (name):  if ((type tag (name)) = [given-first]) report (join (family name (name)) [, ] (given name (name)))
  2. Similarly, define name (display form) ( ).
Morgan: Oh, I see! Now in the rest of the program we can just say things like
for each (contact) of (contact list)  say (name (display form) (contact name (contact))) for 2 secs
Jasmine: It's even better than that! This is where the magic comes in. When we make the Contact ADT, we give it a type tag too:
contact, name: (name) address: (address) phone: (phone): report (list [contact] (name) (address) (phone))
(We'll have to change the selectors, too, and recreate the contact list.)


Then, since contacts have type tags, we can make the same selector blocks work for them, too:
Shouldn't this use join words instead of join? Someone needs to build this project based on the description here (not from their own ideas) to make sure that what we are doing makes sense. I can't do it. I tried. --MF, 7/13/17
name (display form) (object):  if ... if ((type tag (object)) = contact) report (name (display form) (contact name (object))) ...
Ta da! Now your code is just
for each (contact) of (contact list) say (name (display form) (contact)) for 2 secs
  1. Create all that, and make sure Jasmine's "magic" works.
  2. Then add Omar's variants for names in Iceland and Myanmar.