!define TEST_SYSTEM {fit:A} 55
Uncle Bob has been busy with FitNesse lately. If you have been following him on Twitter or if you read his blog post on the subject, then you are aware of his work on Slim.
This post, however, is not about that. It is about something he did to make it possible to execute different tests in different VM’s.
Data Rattle 18
Take a look at this code:
public static int findPositionInInterval(int [] content, int start, int end) {
for(int n = 0; n < content.length; n++) {
int current = transform(content[n]);
if (start <= current && current <= end) {
return n;
}
}
return -1;
}
How does it look? Great? Poor? Is it code with a glaring problem?
Hold that thought for a second and then take a look at this code:
public static int findPositionInInterval(final int [] content, final int start, final int end) {
for(int n = 0; n < content.length; n++) {
final int current = transform(content[n]);
if (start <= current && current <= end) {
return n;
}
}
return -1;
}
I like it better.
The fact of the matter is: mutable state hurts. Unless you’ve done some functional programming you might not realize that it hurts, but it does. It may feel okay to walk barefoot, but if some gives you a comfy pair of shoes you quickly learn that, well, your feet were irritated by pebbles and twigs and there was a better way of walking around, you just didn’t know about it. Fixing state and making it immutable is just like that. When you become used to that style, you notice that it’s easier to reason about your code.
In my mind’s eye, the first snippet is a like a box containing loose parts. If you shake it, it rattles. Parts that don’t need to move are fixed in place by final. In code as brief as this, it doesn’t smell mightily, but it smells nonetheless.
So mutable data is a smell and we can fix it. However, there’s a problem. I’d argue that the second snippet is just a little noisier than the first one. Java forces us to do something special to make data immutable. C# and C++ are the same way: mutable is the default and immutability requires special keywords. There are some languages which make immutability the default, or least make don’t make you pay the price of an extra token to make something immutable. Haskell, OCaml, Scala, and F# all fit into this category. In the older languages, however, we’ll continue to have a lot of rattling data.
Listen for it.
I'm glad that static typing is there to help... 13
The Background
A colleague was using FitNesse to create a general fixture for setting values in various objects rendered from a DTD. Of course you can write one per top level object, but given the number of eventual end-points, this would require a bit too much manual coding.This sounds like a candidate for reflection, correct? Yep, but rather than do that manually, using the Jakarta Commons BeanUtils makes sense – it’s a pretty handy library to be familiar with if you’re ever doing reflective programming with attributes.
The Fact/Intention Gap 40
The other day, I was browsing some code with a team and we came across a cluster of static methods. I looked at them and asked whether they were used someplace else without an object reference. I could’ve done a find references in the IDE, but one of the team members had the answer: “No, they’re just used here.”
“Okay, so why are they static?”, I asked.
“Well, the IDE pointed out that they don’t refer to any instance data, so I made them static.”
Technically, there’s nothing wrong with that. I do the same thing sometimes. I make a method static to document its independence of instance data. But, this scenario highlights something important about static and a few other keywords: their uses can be seen as statements of fact or statements of intention. Static can be read as “Hey, this function doesn’t use any instance data, and you should know that.” Or, it can be read as “I am making this static so that it can be used easily anyplace without an instance.” When you’re trying to read a pile of unfamiliar code, it’s nice to know whether you can count on one meaning or the other.
I don’t think I’ve ever heard anyone articulate this directly, but there’s a tendency in a lot of best practice literature to close the gap between fact and intention. Joshua Bloch’s advice to use make fields final whenever you can in Java is a good example. The traditional advice to make methods private whenever they are not used outside of a class is another.
Part of me feels that closing the gap is a good practice but the fact is, there are holes in it. If you are developing a library or a framework, you do have to write code that may not reflect the facts of your code, but rather will reflect the facts of your code and the code that people write to use it or extend it. Beyond that, it might be overly conservative to reduce visibility of things that aren’t used beyond a particular scope. For instance, imagine a method that is used only by other methods of a class. We understand the invariant of the class and we see that the method could be public. We could make it private now, but that means that anyone who wants to make it public later would have to do some re-analysis to arrive at the answer that we have right now.
The Fact/Intention Gap is a very real thing. Whether we know it or not, we confront it every time we try to understand unfamiliar code. I think there’s only one way to solve it, and that’s to try to separate fact from intention in our languages and tooling. Imagine what it would be like if your IDE gave you a visual indicator for all methods which didn’t use instance data. If it did, you could use static on methods only when you want to indicate that the intention is to use them without an instance.
It seems that IDE developers are moving in this direction. I wonder if any language designers will follow suit.
Markup's Where It's At 15
My first word processor ran in under 8K on a Commodore 64 and that included playing pomp and circumstance. It was adequate. It was markup based. When you wanted to view your work, you previewed the results. (When my friend John got a spell checker add-on, I was really impressed!)
Next, I started using Apple Write (I think that was the name). All of those dot commands on the left margin. I got to the point where I didn’t need to preview, I knew what my stuff was going to look like.
After that, I worked with Word Star on a CP/M emulator running on Apple IIE’s. I actually liked Word Star. I still remember the ^k madness.
Slim 160
Those of you who have been following me on Twitter have heard me talk about Slim. Slim is a new testing front-end and back-end that I’m adding to FitNesse. Here’s what it’s all about.
Elegant Code Interview
A Scala-style "with" Construct for Ruby 107
Scala has a “mixin” construct called traits, which are roughly analogous to Ruby modules. They allow you to create reusable, modular bits of state and behavior and use them to compose classes and other traits or modules.
The syntax for using Scala traits is quite elegant. It’s straightforward to implement the same syntax in Ruby and doing so has a few useful advantages.
Traits vs. Aspects in Scala 89
Scala traits provide a mixin composition mechanism that has been missing in Java. Roughly speaking, you can think of traits as analogous to Java interfaces, but with implementations.
Aspects, e.g., those written in AspectJ, are another mechanism for mixin composition in Java. How do aspects and traits compare?
The Physical Realm Matters 26
In 1997 I took a class called SEM offered by Weinberg and company. It was a rather profound learning experience; I’m probably not aware of much of what I learned. However, there’s one thing I learned that has been coming up lately.
The training was somewhat like an un-conference. We got together and as a group formed the schedule. It was hell. Somehow I ended up at the flip-chart taking notes. After I don’t know how long – certainly an hour, probably more – maybe much less, I wanted out. People were throwing out suggestions and I kept asking the group if anybody would like to take over. I pointed the marker even. I never got out of that role (at the course, that is).