Notes for Assignment #2

The assignment as given in the problem is ambiguous.  How do cells implement the calc() function?  Is there a hardcoded function?  This doesn't need to be answered to do 2.16, but it becomes an issue when implementing the solution in 2.17.

We'll add some more constraints to the problem to answer this question.  Each cell object implements some function.  For our purposes, a function is a mapping from n floating-point numbers to a single floating point number.  For example, the addition function takes two numbers, a and b, as input, and returns their sum a+b as output.  We can regard constant numbers as a special case of a function that takes zero inputs and always has the same output.  For example, in this scheme the number 5 is just a function that requires no inputs and always returns 5.  Following canonical object oriented design, we represent functions as objects.

We need to implement at least the following functions, according to 2.17: +, -,  *, /, %, as well as the constant "function".  We also need to compose these functions together to do calculations like "(a+b)*c".  We can implement function composition by cell dependencies.  First we set up cells A, B, and C which will contain our inputs.  These might be, for example, cells (1,1), (1,2), and (1,3).  Next we set up a cell (call it X) at (2,1) which contains the result of "a+b".  X depends on A and B, and its value is the sum of its dependencies.  Finally we set up a cell (call it Y) at (3,1) which contains the result of multiplying X and C.  Here's the conceptual layout:

A       B       C
X       Y

Here's the data in symbolic form:

a        b        c
a+b    (a+b)*c

Of course, in the actual program we represent things using row/column notation.  When any of a, b, or c changes (via setValue()), cells X and Y should be updated automatically.  For 2.17, you can set up the necessary relationships directly in the code (you don't have to provide a way for a user to set up a function, just a way to input values).  However, it should be possible to write code to let a user type in something like "= 1, 2, + 3, 3, 3, 4" to make the cell at 1, 2 implement a function to add the contents of cells (3,3) and (3,4).  In other words, there should be a clean API for setting functions for cells as well as setting values.  UI code should be separated from the API.

So each cell only needs to implement one "simple" function.  It should be possible to change the function that a cell implements without disturbing the rest of the spreadsheet (and without invalidating pointers to that cell object!).  It should also be possible to add additional "simple" functions with different numbers of arguments without having to change existing code.  (Hint:  Do cells need to know anything about the details of the functions they implement?)

Another requirement which is not explicit in the problem: Cells should cache their last-calculated value.  That way, you don't have to waste time recalculating things when nothing has changed.  Things only get recalculated when a source changes and notifies its dependents that they need to recalculate themselves.

You should also think about how to make the basic calculation engine generic.  Does the notification/dependency engine need to know or care about the details of what the cells do when they update themselves?  Can you make this into a reusable framework?

Bonus points:  What happens when someone introduces a dependency loop?  That is, cell A depends on cell B and cell B depends on cell A?  How can you deal with this?  (Can this ever be useful or well defined?)

Hints:  Think about each object, and what its responsibilities are.  What are the responsibilities of a Cell object?