On this page:
Practice with the Hourglass exam server
Visitors and Generics:   Getting started
Let there be JSON
What’s data without a little self-reference?
Finders, keepers
JSON:   The whole shebang
Challenge problem
8.12

Lab 5: Visitors and Generics🔗

Goals:

Practice implementing the visitor pattern and using generics in a novel class.

Practice with the Hourglass exam server🔗

Before starting the programming exercises below, first we’ll walk through a tutorial on using the Hourglass exam server for next week’s exam.
  • Make sure that you are using either Chrome or Firefox. Make sure that your browser window is not maximized.

  • Navigate to https://hourglass.khoury.northeastern.edu. You should see “Hourglass tutorial” as an active exam, and possibly “Exam 1” as an upcoming exam (if I have it configured in time for lab!).

  • When the TAs see that everyone is logged in, you can all start taking the tutorial exam, to familiarize yourselves with the user interface. If you have questions, you can ask the course staff for help.

Visitors and Generics: Getting started🔗

Copy and paste the following (hopefully) familiar code into Eclipse:
// Represents functions of signature A -> R, for some argument type A and // result type R interface IFunc<A, R> {
R apply(A input);
}
 
// generic list interface IList<T> {
// map over a list, and produce a new list with a (possibly different) // element type <U> IList<U> map(IFunc<T, U> f);
}
 
// empty generic list class MtList<T> implements IList<T> {
public <U> IList<U> map(IFunc<T, U> f) {
return new MtList<U>();
}
}
 
// non-empty generic list class ConsList<T> implements IList<T> {
T first;
IList<T> rest;
 
ConsList(T first, IList<T> rest) {
this.first = first;
this.rest = rest;
}
 
public <U> IList<U> map(IFunc<T, U> f) {
return new ConsList<U>(f.apply(this.first), this.rest.map(f));
}
}

Let there be JSON🔗

JSON is an industry-standard data structure that allows for the storage and sharing of tree-shaped data. Below is a definition of a subset of JSON (more will come later). A JSON can either be a blank value, a number, boolean, or string. In the real world, JSON numbers can have decimal values, but for our purposes we’ll stick to integers.

Yes, technically this should be named IJSON to match our “starts with an I” naming convention, but that just looks silly for this name...

Copy and paste the following definition into Eclipse:
// a json value interface JSON {}
 
// no value class JSONBlank implements JSON {}
 
// a number class JSONNumber implements JSON {
int number;
 
JSONNumber(int number) {
this.number = number;
}
}
 
// a boolean class JSONBool implements JSON {
boolean bool;
 
JSONBool(boolean bool) {
this.bool = bool;
}
}
 
// a string class JSONString implements JSON {
String str;
 
JSONString(String str) {
this.str = str;
}
}

What’s data without a little self-reference?🔗

As the definition for JSON stands in our current form, it’s not very useful. After all, it doesn’t allow for our favorite type of data: lists! Let’s extend the definition to allow for them.

Copy and paste the following definition into Eclipse:
//a list of JSON values class JSONList implements JSON {
IList<JSON> values;
 
JSONList(IList<JSON> values) {
this.values = values;
}
}

Do a plausibility check: does your JSON interface have anything other than an accept method? If so, you have likely not implemented the visitor pattern correctly. Ask a staff member for further clarification. If not, continue onwards.

Finders, keepers🔗
JSON: The whole shebang🔗

As it turns out, there’s even more to JSON than we’ve seen! JSON values can also be a list of pairs, where each pair is composed of a string, often called a key, and an assocated JSON value. Note that in proper JSON data, keys cannot repeat within the same list of pairs; we ignore this for now.

What does this remind you of? What does JSON stand for anyways?

Copy and paste the following definition into Eclipse:
// a list of JSON pairs class JSONObject implements JSON {
IList<Pair<String, JSON>> pairs;
 
JSONObject(IList<Pair<String, JSON>> pairs) {
this.pairs = pairs;
}
}
 
// generic pairs class Pair<X, Y> {
X x;
Y y;
 
Pair(X x, Y y) {
this.x = x;
this.y = y;
}
}

Challenge problem🔗