E-Prime For Software Engineers

I recently restarted reading Quantum Psychology by Robert Anton Wilson. (Not the easiest read. If you put it down for to long you may have to start over.) The most practical thing I’ve gotten from it thus far is the usefulness of E-Prime. You may already use it and not realize it.

To attempt to summarize E-Prime with a single example, consider the following two statements..

  1. Alice’s code is broken.
  2. When I ran the unit tests this morning, all the code last checked in by Alice (according to the logs) failed to pass. Thus, I think her code is broken.

While the first statement is concise, I’d much rather prefer the second because it conveys information about the observer in addition to the observation.

  • The means of measuring brokenness are specified (“the unit tests”). The reader otherwise does not know how the conclusion of brokenness is being determined. Without this information, how is Alice supposed to go about reproducing the issue?
  • A timeframe of failure is specified (“this morning”). Alice may have made the same observation and made fixes shortly after the unit tests were run. The code may have indeed been broken, but only appeared so at the time it was measured.
  • The observations is attributed to the observer (“[w]hen I ran”, “I think”), rather than claiming the an intrinsic state of brokenness about the code.
  • The scope of the brokenness is described (“all the code last checked in by Alice”). All of Alice’s code probably isn’t broken.
  • It is acknoledges that the observation is limited by the means of measurement (“Thus, I think..”). When judged by another means, the code may appear fine.

In short, E-Prime acknoledges that our capabilities or understanding seem to be limited by our instruments of perception (be them eyes, ears, unit tests or ampmeters). Take a looksy at some other examples.


Java Development w/The Eclipse IDE: Five Underused Features

Conditional Breakpoints

Have you ever wanted to suspend execution only under a certain circumstance while debugging, such as every hundredth loop iteration? You can. Set your breakpoint, right-click it, select “Properties”, check “Enable Condition” and enter a condition in normal Java code that will be evaluated every time the breakpoint is hit to determine whether or not to suspend the JVM.

Remote Debugging

Sometimes things work on everybody’s box.. except Bob’s. You’ve watched him produce the issue and have tried to reproduce it on your development machine, but it just ain’t happenin’ for anybody but him. It’s time for a remote debugging session. Start up the JVM on Bob’s box like so..

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,suspend=n,server=y
-jar YourApplication.jar

Within Eclipse IDE on your development machine, select Run -> Debug… and create a new “Remote Java Application” configuration. Select the project that contains the source code, enter Bob’s boxes hostname (or IP address) and the port his JVM is listening on (8000 in this case). Click the “Debug” button to close the dialog and your “Debug” view should now show a new session, connected to Bob’s JVM, and the threads of your application just as if you were debugging it locally. You can set breakpoints and use all the other features described in this article, or impress your mom by starting another instance of your application locally and step through both Bob’s and your own JVM instance simultaneously, side-by-side!

Dynamic Variable & Code Replacement

If you’re debugging a tricky piece of SQL in a servlet that isn’t working right, it’s tempting to abide by the typical write, compile, deploy, run, debug, repeat cycle every time you need to tweak the String. This is tedious and time consuming. Instead, set a breakpoint someplace after the String is defined but before it is used. When you hit it, right-click the variable in the “Variables” view and select “Change Value…”. You can figure it out from there. (Note: This doesn’t seem to work for “final” variables, and so-so with statically declared things.)

If you modify and save a class while you have a debugging connection established, Eclipse will try its best to update the code on the remote JVM without having to restart it. This doesn’t always work (especially if there are stack frames using the changed code), but you’ll be notified if the remote JVM could not be updated. This is especially useful when testing a complex algorithm in a situation that is a pain in the arse to set up.

Custom Code Templates

Typing “fore[autocomplete]” in a block in Java code will add a “foreach” code template that you can fill in using the TAB key. These are customizable, and you can even add your own. For example, I prefix all generated local variable and Iterator declarations with the “final” keyword, and have added my own custom templates for inserting my most frequently used Java 5 annotations. Go to Window -> Preferences… -> Java -> Editor -> Template and have some fun.

Refactoring Actions

All of the refactoring features of Ecilpse IDE are worth learning. I can’t think of one that isn’t. Once you have a method defined and used, there isn’t much reason to manually modify the declaration. “Move”, “Change Method Signature…”, “Pull Up…”, “Push Down…” etc. give you basic, commonly used tools, and actions such as “Extract Interface…”, “User Supertype Where Possible…” etc. provide support for larger jobs. Understanding what all these do helps relieve some of the pain felt when refactoring heavily used, public APIs, and helps keep you focused on the bigger picture by taking care of the details.


If A Unit Test Fails In The Woods, Does It Make A Sound?

No, it doesn’t. Unit tests that execute a large amount of code but fail to make assertions along the way give you a false sense of confidence in the code. They pass when they should fail. These problems, formally known as type 2 errors, are a huge liability for a development team because the tests are believed to be verifying the intended behavior of the software, but are really doing nothing in a really lengthy way.

For a new person maintaining the code under test, the problems worsen. The new maintainer will not understand what the code is supposed to be doing: what it’s currently written to do or what is implied by the possibly out-dated and incomplete unit tests. Good luck finding API documentation if the unit tests suck, and have fun with those future API changes when you must attend to the “unit tests” that need to be updated to successfully add no value to the project, just as they were originally written. No thanks.

Units test exist to prove that software is behaving as intended, not simply “mock” user actions. This means being particular about states of things during a process, and doing mean negative testing by passing nil into that function that clearly requires a non-nil value. The rule of thumb is this: if, for whatever reason, you cannot write, fix, or otherwise finish work for a correct and complete unit test, assert false. You have not proven the software works correctly, so it doesn’t work. Period.


iClock: How To Get The Time.. Apple Style

What the heck do you do with an unsightly Hershey’s Kiss shaped Apple Airport? Turn it into a clock! The RJ-45 and power ports have been relocated as dongles on the back of the unit to make room for the clock battery. The mechanical clock hardware is inside the base station.
iClock (Thumbnail)


Square Foot Garden Beds

I built a couple of square foot garden beds this weekend. The frame is made of redwood 2x2s, and the sides are redwoord planks normally used for fenching. The bottom of the bed is a thick sheet of plywood with holes drilled through it for drainage. The diagonal supporting pieces connecting the load bearing trusses with the vertical posts helps support the weight of the beds contents.

2x6 Garden Bed


Ant Rant

I’ve come to loath ant.

XML is great for a lot of things, but is simply painful for expressing control flow. Now don’t get me wrong, it’s still easier to work with than make; you can use any XML editor or a web-browser to validate the well-formedness of an ant build file. It’s just that programmatic thought isn’t elegantly represented by a tree structure full of angle brackets. Trees are simplifications computer scientists use to fit information into limited structures that can be easily parsed and manipulated, however, as a user of the system I don’t give a flying flock that it uses a standard SAX parser. I do care about defining basic control-flow operations in a natural way, and not having to create artificial work-arounds to cater to the structure of the tree. Elegance, however, is the least of ants problems. It lacks a fundamental development capability that is missing from other build systems such as make and jam, and even long-established shells such as bash: debuggability.

Here’s the deal, plain and simple: if you’re writing a development tool, you must provide some mechanism for easy debugging. “Hello, world!” does not require troubleshooting. Every other real-world “script” does. If you’re automating a build process for a large application, it will have bugs, and when you do get them squashed the system will soon be inadequate and require modification. Now, when I say “debuggability”, I’m not talking about scattered echo/print elements throughout the code or color-coded syntax. I’m talking about stepping through the script line by line and examining the inputs and outputs of every step in the process, just like you would with any C++ or Java program,

The last item in today’s rant is support for basic data structures. Variable passing is pukingly awkard in ant, and calling other targets sometimes requires firing up another ant process. Umm.. riiiiight. “If today is Saturday turn debugging support on, run all known unit tests and send a status report to all team members” is not an unrealistic use of these systems. Debugging this should not be such a chore.


Preston Joins The 21st Century

After an eternity of posting my thoughts, project information and other digital potpourri in a scatter manner across the wire, I’ve finally begun putting the pieces for my personal website. Apparently this is now a requirement for Software Engineers to age past 25, so I have some serious catching up to do. Hooray me.