Enterprise Application Integration As Dispute Resolution?

Sean McGrath has an interesting view of EAI. Basically he thinks is all about dispute resolution.

Computer system A sees the world one way, computer system B sees the world another way, computer system C has a third way and thinks A and B are deeply wrong in how they see the world. etc. etc. The custodians of systems A, B and C need to work together for the good of the greater organization.

That fits pretty well with my experience.

Ruby Backtraces

There is something uniquely happy making about coding in Ruby. However, there are a few things about Ruby that bug me. I think the one I find most annoying is the backtrace. This might seem odd, because it appears to be such a minor thing, but I think the current backtrace noticeably reduces my productivity.

I spent that last 6 years coding in a dynamic language that included argument data in backtraces. Now that I am using languages like Ruby, and Java, that do not include this information I really miss it. Consider the following standard Ruby backtrace.

NoMethodError: undefined method `capitalize' for nil:NilClass
	from /home/pwilliams/projects/tmp/test.rb:18:in `greet_user'
	from /home/pwilliams/projects/tmp/test.rb:14:in `third'
	from /home/pwilliams/projects/tmp/test.rb:10:in `second'
	from /home/pwilliams/projects/tmp/test.rb:4:in `first'
	from (irb):41
	from :0

The only thing you know from this backtrace is that the greet_user method tried to use a nil when it should have used an object that responded to capitalize. You do not even know on what classes these methods are defined. To debug this you have to start by looking at greet_user, if it looks good you move on to third and repeat that process until you find the problem. Or restart the app with debugging and then try to recreate the state that caused the problem.

Now consider the same backtrace with argument information.

NoMethodError: undefined method `capitalize' for nil:NilClass
	from /home/pwilliams/projects/tmp/test.rb:18:in main.greet_user(nil, "williams")
	from /home/pwilliams/projects/tmp/test.rb:14:in main.third(nil, "williams")
	from /home/pwilliams/projects/tmp/test.rb:10:in main.second("williams, peter")
	from /home/pwilliams/projects/tmp/test.rb:4:in main.first("Peter Williams")
	from (irb):41
	from :0

There is, obviously, a lot more information in the second backtrace. Enough, in fact, that you can reliably guess the root cause of the problem. You can probably tell, even without seeing the code, that the bug is in Object#second. It is very unlikely that Object#third was suppose to be called with nil as it’s first argument. It is obvious that the bug is in Object#second, or something that method calls, even though the exception was raised in Object#greet_user. With the current backtrace you are forced to read all the code between the place that raises an exception and the place where the actual bug is located. In many cases this is a lot of code.

The vast majority of bugs can be localize to the correct method using this type of informative backtrace. This means less time spent firing up a debugger or instrumenting the code with write or log statements. It also means that if something goes wrong in the wild you can get a pretty good idea of the problem, simply from the backtrace in the log file.

This is especially frustrating because backtraces are created from an array of data that is passed to Exception object right after they are raised. This array is just a bunch of dumb data extracted from the call stack by the VM, not the call stack, like it should be. This means that argument information cannot be added to backtraces — as far as I can tell, at least — without modifying the VM, which beyond my abilities at the moment. The information in a backtrace ought not be hard coded in the VM. Would it really have been that difficult to reify the call stack and pass that to raised Exceptions?

Added receiver to alternate backtrace format.

Code as Design (Redux)

In this article I proposed that coding is design and not construction. As usual I am late to the party, Jack Reeves pointed this out 13 years ago (thanks Charlie), it discussed extensively on c2.com (What Is Software Design and The Source Code Is The Design), and mentioned on many blogs.

The whole thing has depressed me a bit. I think our industry would be in a lot better shape if we had internalized this idea 10 years ago. Why is it that good ideas, like this one, do not take hold? Anyway, if you have not read those essays by Jack Reeves go do it now.

Coding Is Not Construction

The other day I was talking to a colleague and I compared software development with building a building. I have heard this analogy often and there are a lot of similarities. (For example, most buildings and software systems are, at least partly, custom.) I think there is much to be learned from this analogy when correctly applied, however it is more often than not mis-applied and when it is it leads to all sorts of false conclusions.

The basics of this analogy are that building construction and software development have the following phases:

</p> Inception : Someone has an idea about what to build. Design : An architect/engineer designs the building or software by drawing a set of picture and writing some text about the thing to be built. Construction : A bunch of labors use the documents produced in design step to produce the final product. Profit! : Sell the building or software.

</dl>

People often equate the construction to coding when applying this process to software development. The RUP process, for example, uses these phases. But coding is design, not construction. The construction phase of building a building is more equivalent to compiling in software development. This is a bit easier to see if you look at what the output of a project is. In a building project the output is the building. In a software development project that output is it is the executable, and it’s supporting data, not the code. In the software industry we have already completely automated the construction phase. I think that we already know, sub-consciously at least, that coding is not construction because we call systems like make, ant, etc. “build” tools, implying that they construct the final product.

When you write code you are not producing the final product, you are producing a set of instruction to the construction team — the compiler and build tool — in much the same way an architect of a build produces instructions in the form of a set of blue prints. This distinction may not seem particular important at first, but the, incorrect, equation of coding to construction leads to some bad conclusions. Some example are component-based software engineering and certain types of out-sourcing.

What we call designs in software development are more like the artist’s view of a building than what architects produce as input to the building construction phase. While these nice pictures are useful, I think we have done our selves a disservice by calling them designs. Calling them designs implies that all the necessary information for construction is present and it never is. Design choices keep getting made until the day you freeze the code.

If we want to improve software development what we need are better construction teams, not off-the-shelf walls or structural designs for each floor done in different lower-cost-countries. Architects do not have to design a house down to the detail software developers write code because physical construction teams can fill in a lot of detail by themselves. I think this is why DSLs are often a big win. The compiler (or interpreter) for the DSL can fill in a lot of detail based on the it’s understanding of the domain.

Fixed a couple of spelling errors.