Skip to content

Resources design exercise

jennalwise edited this page Sep 28, 2017 · 15 revisions

Typestate

Most real world problems or scenarios can be solved or modeled with an emphasis on state, sometimes for the better. For example, consider the state chart diagram below used to model the state of a wallet containing a student Id and a license.

Wallet State Chart

Resources

[NEEDS WORK]

For each task the student Id and license will be referred to as resources that have the following properties/restrictions when implemented in code:

  • No duplication of resources
    • Can only be assigned to one modifying reference variable at a time
  • Resources must be passed, returned, or released
    • Letting resources go out of scope without explicitly passing, returning, or releasing them is forbidden

Task 1

Imagine you have a programming language that allows you to represent state chart diagrams quite nicely, as seen below. The Wallet state chart diagram is implemented as a class with state member variables and transaction methods. The state member variables contain their own member variables (resources) appropriate to each state and the transaction methods contain one or more transitions (-><state name>) from the current state to another.

However, the code below is incomplete as resources are not being handled properly. Your task is to add to and/or modify the code below to ensure the license and id resources are handled properly by following the rules listed in the Resources section above. Do not limit yourself to known language constructs; ie. make up any language features you may want. We want to see the kind of code you would want to be able to write.

class Wallet {

  state HasLicenseOnly;
  state HasStudentIdOnly;
  state HasLicenseAndStudentId;
  state Empty;

  License license available in HasLicenseOnly, HasLicenseAndStudentId;
  StudentId id available in HasStudentIdOnly, HasLicenseAndStudentId;

  transaction addLicense(License newLicense) available in HasStudentIdOnly, Empty {
  	if (in HasStudentIdOnly) {
  		->HasLicenseAndStudentId
  	} else {
  		->HasLicenseOnly
  	}
  }

  transaction addStudentId(StudentId newId) available in HasLicenseOnly, Empty {
  	if (in HasLicenseOnly) {
  		->HasLicenseAndStudentId
  	} else {
  		->HasStudentIdOnly
  	}
  }

  transaction addLicenseAndStudentId(License newLicense, StudentId newId) available in Empty {
  	->HasLicenseAndStudentId
  }

  transaction removeLicense() available in HasLicenseOnly, HasLicenseAndStudentId {
  	if (in HasLicenseOnly) {
  		->Empty
  	} else {
  		->HasStudentIdOnly
  	}
  }

  transaction removeStudentId() available in HasStudentIdOnly, HasLicenseAndStudentId {
  	if (in HasStudentIdOnly) {
  		->Empty
  	} else {
  		->HasLicenseOnly
  	}
  }

  transaction removeLicenseAndStudentId() available in HasLicenseAndStudentId {
  	 ->Empty
  }
}

Task 2

For this task you will be given various code design options for resource handling based on the Wallet code example from Task 1. Your job is to answer the questions following each set of code samples.

Code Sample Set 1

//Option 1
transaction putInLicenseAndStudentId(License newLicense, StudentId newId) available in Empty {
  ->HasLicenseAndStudentId(license = newLicense, id = newId)
}

//Option 2
transaction putInLicenseAndStudentId(License newLicense, StudentId newId) available in Empty {
  newLicense -> HasLicenseAndStudentId.license
  newId -> HasLicenseAndStudentId.id
  ->HasLicenseAndStudentId
}

//Option 3
//specialized state constructor
state HasLicenseAndStudentId(License license, StudentId id);

transaction putInLicenseAndStudentId(License newLicense, StudentId newId) available in Empty {
  ->HasLicenseAndStudentId(newLicense, newId)
}

//Option 4
transaction putInLicenseAndStudentId(License newLicense, StudentId newId) available in Empty {
  ->HasLicenseAndStudentId
  license = newLicense;
  id = newId;
}

Questions

  1. What do all of the code samples above attempt to accomplish with respect to resources?
  2. For each option above briefly describe what the transaction body is doing.
  3. For each option above briefly describe how it differs from the other three options.
    • The differences can be syntactic and/or conceptual.
  4. Rank the options from 1 to 4 with 1 being your favorite and 4 being your least favorite. Briefly indicate the reasons for your choices.

Code Sample Set 2

//Option 1
transaction removeLicenseAndStudentId() available in HasLicenseAndStudentId returns Resources {
  Resources resources = ->Empty

  console.out("License with license number " +
    resources.license.licenseNumber + " is being removed.");
  console.out("Student Id with Id number " +
    resources.id.idNumber + " is being removed.");

  return resources;
}

//Option 2
transaction removeLicenseAndStudentId() available in HasLicenseAndStudentId returns (returnLicense, returnId) {
  (returnLicense = license, returnId = id) = ->Empty

  console.out("License with license number " +
    returnLicense.licenseNumber + " is being removed.");
  console.out("Student Id with Id number " +
    returnId.idNumber + " is being removed.");

  return (returnLicense, returnId);
}

Questions

  1. What do all of the code samples above attempt to accomplish with respect to resources?
  2. For each option above briefly describe what the transaction body is doing.
  3. For each option above briefly describe how it differs from the other option.
    • The differences can be syntactic and/or conceptual.
  4. Choose your favorite option. Briefly indicate the reason for your choice.

Code Sample Set 3

//Option 1
transaction licenseAndStudentIdExpire() available in HasLicenseAndStudentId {
  console.out("License with license number " +
    license.licenseNumber + " has expired.";
  console.out("Student Id with Id number " +
    id.idNumber + " has expired.";

  release(license, id);
  ->Empty
}

//Option 2
transaction licenseAndStudentIdExpire() available in HasLicenseAndStudentId {
  ->Empty

  console.out("License with license number " +
    old.license.licenseNumber + " has expired.";
  console.out("Student Id with Id number " +
    old.id.idNumber + " has expired.";

  release(old.license, old.id);
}

//Option 3
transaction licenseAndStudentIdExpire() available in HasLicenseAndStudentId {
  (returnLicense = license, returnId = id) = ->Empty

  console.out("License with license number " +
    returnLicense.licenseNumber + " has expired.";
  console.out("Student Id with Id number " +
    returnId.idNumber + " has expired.";

  release(returnLicense, returnId);
}

Questions

  1. What do all of the code samples above attempt to accomplish with respect to resources?
  2. For each option above briefly describe what the transaction body is doing.
  3. For each option above briefly describe how it differs from the other options.
    • The differences can be syntactic and/or conceptual.
  4. Rank the options 1 to 3 with 1 being your favorite and 3 being your least favorite. Briefly indicate the reasons for your choices.