Sunday, August 9, 2009

Why I do not like Statecharts

Statecharts are used all over the place for "Model Based Design" of software systems. I have always felt uneasy about the "graphical" programming language -- the marketing speil around statecharts always seemed too glib to me. Only recently have I been able to articulate this uneasiness clearly enought to satisfy myself.

First let me list down my complaints against statecharts and then address them one by one:
  1. Do Statecharts actually reduce the cost of software development or does it just move around the costs?
  2. Are AND and XOR actually good enough to express requirements and designs?
  3. Are Statechart models specifications or are they implementations?
  4. What is this "concurrency" all about?
One of the big "advantages" of Statecharts is that it is a "high level" "Domain Specific Language" that effectively addresses the problem of programming complex mode based behaviour (especially in particular domains such as embedded systems). However, it seems to me after maintaining and programming applications for a couple of months using Rhapsody, that this is not true. Statecharts give a false sense of simplicity for complex logic, and this results in engineers quickly adding a transition here and changing a guard there in order to modify the behaviour of an existing statechart. The generated code is complex enough that no one bothers to look at the code and/or reviews it. The fact is that Statecharts do not simplify complex logic, they just provide a couple of mechanisms for "decomposing" the complexity. People often do not realize that this decomposition also has to be very carefully done to avoid unintended behaviours, and Statecharts do not provide any mechanism for "analysing" the decomposition. In fact, my guess that the most effective part of development using tools such as Rhapsody is the fact that it helps in organizing interfaces between different modules using concepts such as ports. For example, if there is a push in an organization to adopt Model Based Development for even legacy code-based projects (and this is indeed there in a number of organizations), the last part that I would convert to "models" is the behaviour -- converting code to a model will not add to the maintainability of the project in any way.

Coming to the structuring mechanisms actually provided by Statecharts, AND and XOR sub-charts are what come immediately to mind. First, I feel that the way in which these are presented is not very helpful -- saying that AND charts help to model "concurrency" is very unhelpful. It is much more valid to say that AND charts allow decomposing complex behaviour into "orthogonal" state machines. Basically the emphasis should not be on the concurrency, but on a particular way of decomposing complexity. In fact, the theory of automata gives TWO canonical ways of decomposing state-machines -- one is the "parallel" composition which has been popularised by Statecharts; and the other is "serial" composition which is infact more generic then "parallel" composition and subsumes it. Similarly, the XOR decomposition of statecharts is used to "zoom" into one part of the behaviour and specify it; but the XOR decomposition as provided by statecharts is limited by "graphical" limitations -- the zoom is much more naturally specified by logical predicates, and a graphical notation is a very poor representation of the "boolean algebra" structure of the zoom predicates-- this is a case of a "picture being worth ONLY a thousand words"

There is this idea that Statecharts are good for "specifying" behaviours. The act of specification is more than just putting down on paper our understanding of a behaviour -- this is simply a task of transliteration. Specifying behaviour (especially in early stages of software) implies that the specifier does not yet fully comprehend all aspects of the required behaviour. In this case the specifier needs tools for "exploring" different aspects of the behaviour, of checking if he has contradicted himself in places, and if he has ensured that all corner cases have been considered. Statecharts do not provide tools for doing these activities.

Let us first consider the issue of "contradiction": in Statecharts we could map this to "non-determinism". However non-determinism is clearly not the same as "contradiction" - non-determinism could arise because we have abstracted out some details while specifying and in this case is a signal to "un-abstract" some parts. This is what most software theoreticians/practitioners mean when they talk of the "power of non-determinism" -- they are really talking of "abstraction". In a specification such non-determinism should not occur unless there really is no-decision to be made, and if any one of the non-deterministic behaviours is acceptable in the system -- if this is not the case it is really a case of too much abstraction in the specification. The other case for non-determinism is when we want to have an environment that we do not control (or build) -- in this case, a specification will not lead to implementation and issues of the quality of specification are pretty much moot.

Now for "completeness". The semantics of statecharts has some notions of "undefinedness", but this has more to do with the so-called "temporal paradoxes" introduced by the semantics -- some variants such as Stateflow do not have a logical paradox, but lead to a very complex situation where the language designers have thrown up their arms and swept the problem under the carpet by "disallowing" it. Coming back to the semantics, it is pretty much an execution semantics and the focus is in ensuring that as far as possible, there is a well-defined behaviour for all possible inputs. When the semantics itself tries hard to "complete" a specification, what hope is there for talking of "incompleteness" in the specification??????

Finally, what is all this talk of modelling "concurrency" in statecharts? All that statecharts provide is some syntactic sugar for "parallelism" (see also my rant about "parallelism" and decomposition above). This again only masks the complexity and does not help in analysing the complexity. If I really want to have a high-level model of concurrency and message passing, I would rather use something like Promela and the model-checking support provided by SPIN, which actually helps in analysing the concurrent behaviour.

All in all, Statecharts were proposed in the late 80s and they were a breakthrough in computer science in many ways. They were proposed by Harel who was (and is) one of the foremost minds in computer science. However, I feel that because they were proposed by such a towering figure, and because of the considerable tool support, there are not enough people challenging it and questioning its "marketed" utility. Two decades down the line, I think it is high time we seriously re-evaluated Statecharts from every respect.