Friday, 23 Jul 2004
Single Assignment Considered Error-Prone
Fow a while now, I've been experimenting with concepts from functional
programming in Java, immutable objects in particular. Advocates of
functional programming claim that it makes programs easier to write,
debug, and understand. (See Why
Functional Programming Matters.) After getting a bit more
experience with it, I'm not so sure about that. Functional
programming can be error-prone in its own way.
In particular, a common error I make is to refer to the wrong state
when modelling a state machine. Here's a simple example:
final User user = domain.lookup(userId);
// lots of code here
// change the user
final User next = user.withEmail(newEmail);
// more code here
// bug: returned the wrong user state!
return new Result(user, otherStuff);
The bug comes from having multiple states of an object in scope, all
but one of which are obsolete. It becomes very easy to reference the
wrong state, particularly when moving lines of code using
cut-and-paste. I've tried given them clearer names (like "before" and
"after") but that only helps a little.
I think the best solution is to give up on single assignment. Use one
mutable variable to keep track of state:
User user = domain.lookup(userId);
// lots of code here
// change the user
user = user.withEmail(newEmail);
// the code here can only refer to the last state.
return new Result(user, otherStuff);
It's clearer and the function is still side-effect free, so what's the
harm?
It seems like mixing up states would happen just as easily in pure
functional programming languages like Haskell. I wonder what they do?
Maybe adding mutable local variables to language like that would be an
improvement?
respond | link |
/code
|