The Mathematics of Engineering

5 comments
Suppose you need to write a new class. After thinking a bit you realize there are two ways to implement the class. The first one is slow but thorough (henceforth- ST): it will take you ten days to complete, but it can easily evolve to support a new set of features. Let's assume that a typical extension of this implementation will require five days of work.

The second way is quick and dirty (QD): you will need only one day to complete the task, but the resulting code will not be very scalable (that is, it will be difficult to extend it to support additional features).

So which approach should you choose? To answer this question we estimate the total development time needed for supporting the extended set of features.

  • The ST approach requires 15 days (10 for the initial version, 5 for the extension).
  • The QD approach requires at most 16 days (1 for the initial version, then throwing away the code and re-programming for 15 straight days)
At first sight we note that the penalty of choosing the QD approach was just one day of work (the amount of time required for the QD implementation)

But, this is just one side of the story. Here is why you should prefer the QD approach despite this penalty:
  1. It is possible that (eventually) you will not need the extended features. Thus, you will waste nine days of work for something that will never be used.
  2. It likely that you can reuse some of the QD code instead of throwing it away. For the very least you can reuse your test cases (remember: we assumed a similar interface). This can dramatically reduce the penalty.
  3. Getting something to a working state is very important. Other members of your team, who need this class, may have to wait until you finish writing it. Thus, by releasing your class sooner (i.e., choosing the QD approach), you increase the overall throughput of your team. This gain is well worth the QD penalty.
Of course, if you are about to take such a decision you will have to make these time estimates yourself based on the task at hand.

Whatever your final decision is, remember this simple moral: The penalty that the QD approach carries is much smaller than what it initially seems.

Hacking a compiler

2 comments
Q: How can I discover where a certain compiler operation is implemented?
A: When you hack (in the positive sense of the word) a compiler you have one important factor working for you: Unlike most programs, a compiler has well defined semantics. This means that you can predict its behavior when you give it a certain input. In the domain of compilers an input is source code to compile.

So, the trick for placing a breakpoint, is to use the compiler's error messages. Suppose you want to find the location where the type compatibility checking takes place. You start by writing a program that creates a type error. Then compile the program and write down the error message that you get: "Incompatible types\n Found:....\nRequired:...\n". Then use your favorite grep-like utility to find the line where this string appears and that's basically it.

The reality is a bit more complicated than that. In Sun's Javac compiler the error messages are listed in a properties file: com.sun.tools.javac.resources.compiler.properties The messages are keyed by strings that look like this: "compiler.err.prob.found.req.1". So you need to find the key in this file, then search this key inside the compiler's code base. When you do that you need to remove the prefix "compiler.err" (it is automatically added by the error reporting module).

So to conclude our little example, you actually need to search for "prob.found.req". This string has four occurrences, all inside com.sun.tools.javac.comp.Check.java. You can now place a breakpoint in each of these places. One of them is what you need