Rubric for Problem Set 1

A rubric in this context is an explanation of how a problem set was graded. The solution may be found on the course website.

The comment sections below are in increasing order of severity. The first one is a matter of style; your choice. (Labeled "Advisory.") The second is a matter of "convention," which is also stylistic, but our choice. No points were taken off for violating conventions, but they will on later assignments (after PS2). After the conventions come substantive flaws for which points were taken off (out of 10). The number taken off is shown in square brackets at the top of the paragraph describing the flaw. They are in no particular order.

Advisory:

You don't have to write "-1 * e" ; you can just write "- e".

Convention:

Don't put identifying information in your files unless we ask you to. I like to grade anonymously, and Canvas lets you do that.

Scala style calls for indentation by 2 spaces; if your editor has default indentation = 4 spaces, or, worse yet, by a tab character, change the setting. If indentation by tab is wired in, find a new editor. (Tab stops are defined by the reader of the code, not the writer; it's unpredictable what the code will look like to the reader if it contains tabs.)

A colon used to declare a type should have no space before it and one space after it. Write "x: Int," not "x:Int" or "x : Int". (Don't hesitate to leave space around other infix operators (both before and after). This is especially true if the operator is more than one character long. But even when the operator is a familiar one-character symbol, isn't "xNew + wOld" more readable than "xNew+wOld"?)

Avoid using the return statement or any other "nonlocal goto" except throwing exceptions. The correct way (as far as CS470/570 is concerned) to exit a loop "prematurely" is to add a (typically Boolean) variable whose value may be set when the condition requiring premature exit is detected, and read in the while condition.

As a continuation of that last point, don't implement a simple loop as a recursion for the sole purpose of letting return serve as a substitute for the break statement deliberately left out of Scala. It's really annoying to have to scan a function definition looking for each point where return is used and figuring out what conditions obtained at that point in order to understand all the ways the loop can terminate. Using Booleans (with mnemonic names) makes it transparent what conditions obtained.

As a rule, move all I/O to the top-level App (or to subroutines called by that App just to perform repetitive I/O tasks). The job of all other objects and methods is to perform computations. Because I/O is specific to the particular use of a method, putting it in the method tends to spoil it for other uses. Methods that perform pure computations (on immutable data structures) are more reusable. By the way, we won't see many examples of mutable objects such as MyWeight again in this course.

Names of objects and classes must start with a capital letter. The object or class defined in FavMovie.scala should be called FavMovie, not favMovie or favmovie or fav_movie. (Readers should never have to read the code to figure out what the name of a program is. Either the program should have the same name as the file, or there should be clear instructions on what its name is. Cf. MyWeightApp in MyWeight.scala.)

Substantive:

  1. [R1/-2]

    If the instructions call for MyWeightApp to be an App that prints something when run, then that's what's supposed to happen. It's not enough that the correct output can be obtained by calling one or more programs with the wrong name, especially if a program with the right name exists in the file.

  2. [R2/-1]
    A program or object specification ("spec") should specify how the program or object behaves, not how it is implemented. The person writing the spec doesn't know how it's implemented, because it can't be implemented until the programmers see the spec. Putting in detailed instructions about variables, expressions, control structures etc. ties the programmers' hands in ways the spec writer can only guess will be helpful; such guesses are almost always wrong, which is why programs often have to be radically revised from what the programmer initially supposes is the correct structure.

    I took only one point off for violating this rule because (as explained in the solution for problem 2B) I violated the rule in my original spec; and perhaps you never took a course about software engineering, or a course involving programs large enough that avoiding chaos required software-engineering techniques. Don't worry, we won't write large programs in this course either, but if you violate this principle in the future (and I don't), I might take more points off.

  3. [R3/-2] If the instructions call for MyWeightApp to be defined in the same file as MyWeight, do it that way.
  4. [R4/-1] The instructions said clearly that any exceptions should be caught.
  5. [R5/-2] Throwing an exception when the maximum time horizon is exceeded makes no sense; in the program's main loop (or recursion), all you have to do is include the time horizon in the condition determining whether the loop (or recursion) should continue.
  6. [R6/-2] Don't use Ints for the job Booleans were designed for, even if you secretly believe there's an integer stored somewhere as the representation of that Boolean. (Even if there is, why would it be a 32-bit Int when an 8-bit Byte would do?) Declaring a variable an Int allows it to be set to any of 232 values, all but two of which are actually meaningless. Why make trouble for yourself?