[This is long and in parts is something of a rant. You have been forewarned!]

The current Parrot configuration system is essentially a harness. P::C::runsteps() will go from one step to the next regardless of whether the first step completes successfully. So critical failures don't cause configuration as a whole to abort.

But 'critical' is in the eye of the beholder.

Take configuration step #1, init::manifest, for example. Currently, when it fails to locate all the files listed in the MANIFEST, it complains -- or, more precisely, acks -- about missing files and then allows config step #2 to begin. When this has happened to me, I tend to make a mental note, I continue to hack on whatever I was doing, and then resolve the question of the missing file before my next 'svn ci' and 'perl Configure.pl'. That's because I'm usually more interested in what's happening in step #10 or #12 than I am in immediately correcting step #1. But, as we saw recently, other dedicated Parrot developers may feel that step #1 should cause the whole configuration process to come to an immediate halt.

(I should note that init::manifest is more polite than other config steps in that it prints an helpful failure message to STDOUT when it fails.)

The problem is: We have no way by which to 'objectively' measure the relative criticality of the particular configuration steps. If we were to decide that, say, a failure in inter::progs is so serious that configuration should grind to a halt, what is there to prevent someone from saying, "Hey! What about step x::y? Isn't that equally as critical as inter::progs?"

So I think our alternatives are either:

(1) Retain the current system, in which the failure of one step does not prevent Configure.pl from attempting the next step.

(2) Jettison the current system completely and require that each config step demonstrate (say, by returning a true value rather than 'undef') that it has completed successfully.

(3) Have the Parrot leadership make an explicitly subjective judgment that some config steps are more equal than others and allow them to have a different interface (specifically, different return values) from all the others.

Personally, I think (1) is the best choice.

But that doesn't make me a fan of the current configuration system by any means. The current system was designed long before I joined the Parrot project, so I have no ego investment in it.

The current system consists of 58 separate programs which vary markedly in terms of purpose and complexity. The only things they share in common are (a) that they are required to have a $description and a sub runstep() to fit into the harness run by Parrot::Configure::runsteps and (b) that they return either a Parrot::Configure::Step object or 'undef'. The most common reason to place code in a subroutine is code re-use, but none of the 58 different step runstep() subroutines is ever re-used. We could just as easily rename each of them main() and pretend we're writing bad C.

The fact that virtually all the functionality of any particular Parrot configuration step is packed into a single runstep() subroutine means that for such a subroutine it is darn near impossible to follow the maxim, "Have your subroutine do one thing and do it well."

It also means -- and here comes the place where I have major ego investment -- that many of the step runstep() routines are difficult to test thoroughly. Since June I have been writing tests for the config/*/*.pm packages in the reconfigure/ branch and, as they have matured, have brought them into trunk. But the fact that only about 13 of the 58 config steps are yet represented by tests in t/configure/ is testimony to the difficulty in thoroughly testing many of them.

And I hate code that I cannot test thoroughly. (In fact, I'm going to use it as an example of untestable and uncoverable code in my talk on coverage analysis at Pittsburgh Perl Workshop next month.)

Nonetheless, the fact is that while the design of the Parrot configuration process is less than ideal, it is good enough for most of us most of the time. Most of the time, it does not prevent the compiler developers from working on the PMCs, the C code and all that other mysterious (to me) stuff. Most of the time, the configuration process does not prevent the language developers from trying to port languages to Parrot. So, as much as I dislike aspects of the configuration process's design, it is not the main problem with Parrot right now -- either code-wise or human-wise.

I'm eager to work with other Parrot developers at planning for the evolution of the configuration process (e.g., the file-based configuration suggested by particle), but I think we should be cautious about overhauling the current system and even more cautious about allowing particular configuration steps to behave differently from others.

kid51

Reply via email to