Tuesday, June 17, 2003

Debating with Knives

A couple of years ago at OOPSLA I saw a wonderful panel format. On stage there was a table, short side facing the audience. People sitting on one side of the table had to support the motion, those on the other had to oppose it. At any time, anyone could stand up, walk to the other side of the table, and tap someone on the shoulder. Those two people then swapped places: the one arguing for then had to argue against. After a while, they let members of the audience come up and tap on shoulders too.


At last night’s Pragmatic Practitioner dinner here in Dallas we tried the same thing. After the meal was cleared away, we used our left-over knives to indicate the position we were taking: a knife lying in the customary end-on position meant you were supporting the statement “statically typed languages are better than dynamically types ones.” A knife lying crossways meant you were opposing the motion. We started with knives alternating around the table, and tried to maintain a kind of parity: you could only swap your knife’s position if someone else did. Every now and then we had a group swap, where every knife switched.


The result was a fun and not too serious debate. It was good to be able to argue both sides of a position; very few things are black and white, and it’s nice to be able to acknowledge opposing points of view.


Now I’m wondering if the same technique could work in a business setting. Could it take the heat out of the discussions we have about architectures, design, timescales, and so on?

Wednesday, June 11, 2003

Construction Methods

A recent thread in ruby-talk reminded me of a change in the way I’ve been writing classes over the last year or so.


In the past, I used to enjoy the ability to overload constructors. To create a rectangle given two points, I might write:


  Point p1 = new Point(1,1);
Point p2 = New Point(3,4);

rect = new Rectangle(p1, p2)

Alternatively, I might want to create a rectangle given one point, a width, and a height:


  rect = new Rectangle(p1, 2, 3);

Inside class Rectangle, I’d have two constructors:


  public Rectangle(Point p1, Point p2) { ... }

public Rectangle(Point p1, double width, double height) { ... }

The problem with this approach is that is breaks down when the different styles of constructor can’t be distinguished based on argument type. It also makes the code harder to read: if you see


  new Rectangle(p, r, t);

where are the hints as to what’s going on?


So now when I write a class with multiple construction requirements, I tend make the constructor itself private, so it can’t be called outside of the class. Instead I use a number of static (class) methods to return new objects. These methods can have descriptive names (often with_xxx, for_xxx, orhaving_xxx), and I don’t have to worry about parameter types. As a silly example, the following Ruby class has three constructor methods, letting me build a square by giving its area, its diagonal, or a side. What it won’t let you do is construct the object by calling new, as the constructor itself is private.


  class Square
def Square.with_area(area)
new(Math.sqrt(area))
end

def Square.with_diagonal(diag)
new(diag/Math.sqrt(2))
end

def Square.with_side(side)
new(side)
end

private_class_method :new

def initialize(side)
@side = side
end

end

s1 = Square.with_area(4)
s2 = Square.with_diagonal(2.828427)
s3 = Square.with_side(2)

Of course this is nothing new to Smalltalk folks (nor is it particularly new or revolutionary elsewhere). However, it does seem to be less common than it should be in the Java world. Just because you canoverload constructors doesn’t mean that it’s the best way to code your classes.

Thursday, June 5, 2003

Change Control is Location Independence

Brian Marick just blogged on Configuration Management. He talks about how he uses CM differently in work and personal contexts: in a work context he uses it as an audit and exploration tool, but at home it is basically a big UNDO button.


I’m guessing that Brian primarily uses a single computer at home, or that he has different computers dedicated to different tasks. Andy and I don’t. I have four desktops and two laptops I use pretty regularly (although the Powerbook has become my workhorse machine recently). And I migrate my development between them in a pretty ad-hoc way. If I happen to be in front of my big monitor when I realize how to add something to RDoc, I’ll start typing in to my Linux box. If half way through I have to take Zachary to his karate class, I’ll check in what I have, check it back out on the Powerbook, and carry on while I wait for him. I can work on articles, coding, books, or whatever on just about any of my machines. If I’m in a hotel and I need something, I can just check it out. Even this blog is stored under CVS (and served from it as well: all I have to do to post an article is check it in).


The are many other good reasons for using source control, but freedom from a particular hard drive is a significant one for me.

Tuesday, June 3, 2003

Dynamically Scoped Variables

Whenever I write complex systems, I find I need a way to keep context information lying around. For example I may pick up a set of user preferences for colors at the top level of some code, but then I need them when I get fifteen levels deep, somewhere within the bowels of a component’s paint method. Or perhaps I get a database connection at the start of request handling, but then need to use it when I get deeply nested inside some application code.


These types of scenario seem to have no easy answer. Sometimes you solve it by passing a common parameter to all your methods. This parameter then contains references to all the context information needed by the application code. But this is a messy approach: it means that all your methods have to accept and pass on a parameter that they don’t necessarily need themselves.


A variant of the above is to pass the context object to every constructor, and then store a reference in an instance variable. This suffers from the same drawbacks; every object is carrying around payload that it might not itself need.


Sometimes you can get away with using singletons to store this kind of stuff, but this rapidly breaks down (or at least becomes unwieldy) in the face of multi-threading.


There is another answer, though: dynamically scoped variables.


Most languages offer lexically-scoped variables. When a program is compiled, variable names are looked up by first examining the enclosing scope, then the scope that lexically encloses that scope, and so on. Variables are bound according to their static location in the source code.


However, another kind of variable binding is remarkably useful for passing around context information. Dynamically scoped variables are resolved not at compile time but at run time. When a dynamically scoped variable is referenced, the runtime looks for an appropriate variable in the current stack frame. If none is found, it looks in the caller’s stack frame, and then in that stack frame’s caller, and so on. That way you can set the context in one method, then call multiple levels deep, and still reference it.


Many languages offer dynamically scoped variables: Lisp, TCL, Postscript, and Perl to name a few. In Perl, you could use local to achieve the effect:


  sub update_widget() {
print "<$color>$name</$color>\n";
}

sub update_screen() {
update_widget;
}

sub do_draw() {
local $name = "dave";
local $color = "red";
update_screen();
}

Although easy to use, locals in Perl are hard to control. And Perl’s features don’t help me much anyway; I needed a Ruby solution. I came up with something that’ll let me do the following.


  def update_widget
name = find_in_context(:name)
color = find_in_context(:color)
puts "<#{color}>#{name}</#{color}>"
end

def update_screen
update_widget
end

with_context(:name => 'dave', :color => 'red') do
update_screen
end

The with_context block establishes a set of dynamic variables (the parameters to the call). Within any method called at any level during the execution of the with_context block, a call to find_in_contextlooks up the appropriate dynamic variable’s value and returns it.


The implementation I came up with allows nested dynamic scopes, so the code:


  with_context(:name => 'dave', :color => 'red') do
with_context(:name => 'fred', :color => 'green') do
update_screen
end
update_screen
end

outputs:


  <green>fred</green>
<red>dave</red>

The actual implementation itself is a tad ugly (and I’d welcome alternatives), but right now I view it as something of a singing pig.


  def with_context(params)
finder = catch(:context) { yield }
finder.call(params) if finder
end

def find_in_context(name)
callcc do |again|
throw(:context, proc {|params|
if params.has_key?(name)
again.call(params[name])
else
raise "Can't find context value for #{name}"
end
})
end
end

Update…


And of course, it took less than eight hours for a more elegant implementation to surface (I love the Ruby community). Tanaka Akira posted:


  def with_context(params)
Thread.current[:dynamic] ||= []
Thread.current[:dynamic].push params
begin
yield
ensure
Thread.current[:dynamic].pop
end
end

def find_in_context(name)
Thread.current[:dynamic].reverse_each {|params|
return params[name] if params.has_key? name
}
raise "Can't find context value for #{name}"
end

Update #2…


And Avi Bryant massages the original into this masterpiece of minimalism…


  def with_context(params)
k, name = catch(:context) {yield; return}
k.call(params[name] || find_in_context(name))
end

def find_in_context(name)
callcc{|k| throw(:context, [k, name])}
end

Sunday, June 1, 2003

The Joy of Lego

Martin Fowler has put up a link to an IEEE Software Design Column article by Rebecca Parsons called Components and the World of Chaos (pdf).


In part, the paper argues that assembling large numbers of components could potentially lead to behavior that would be hard to predict ahead of time: the interaction of these simple components could lead to complex (or emergent) behavior. Components could interact in ways not foreseen by their original designers.


The paper suggests that this might be a bad thing: it would be hard to predict the exact behavior of these component-based applications in advance, and so they would be risky to deploy.


I can see that argument: even without worrying about the distribution of heterogeneous, multi-vendor, high-level components, I know that I’ve been bitten in the past by different parts of systems interacting in ways that I hadn’t expected.


But at the same time, a part of me wonders if there isn’t some potential magic to exploit here. Say we can find ways of specifying the stuff we definitely don’t want to happen, perhaps by specifying business rules as invariants or mini-contracts, stuff such as “you can’t sell something if it isn’t in stock,” and “you can’t refund more that you were originally paid,” that kind of thing. These rules define a kind of business baseline: something that the application must do. We implement the rules at some kind of meta-level; some are associated with individual components, and others, specified in the component assembler/aggregator layer, apply to the component’s interactions. They give us our safety net.


But we don’t try to box the application in totally. Instead, we wait to see if other, potentially unexpected behaviors emerge. Our business rules act as some form of guarantee that the new behavior won’t hurt us, but they don’t prevent us from benefiting from any new and valuable behavior that might pop up.


Can we really produce working systems where we don’t know all the ways in which it will behave up-front? Just look at The Sims (or Lemmings, for those feeling nostalgic). Look at the way folks are using scripting languages to produce small component-like interfaces for existing applications, and then using those interfaces to combine the applications in unexpected ways. Clearly at some level we can. Right now we can’t do the same kind of thing for business applications: we don’t know enough about specification techniques to be able to plug all (or even most of) the holes up-front. But in the next few years, perhaps we will. And perhaps systems such as Naked Objects suggest how some of lower-level building blocks might work.


All the truly interesting behavior is emergent (if for no other reason that if we can predict it ahead of time, it really isn’t too interesting when it happens). And this emergent behavior has an amplifying effect on our productivity as developers: combine simple things using elementary rules to produce a whole that has complex and rich behavior. So I’d argue that having component-based architectures produce systems with emergent properties is not a risk: it’s a requirement. We’re just not there yet.