http://qs1969.pair.com?node_id=413132


in reply to Cyclomatic Complexity of Perl code

This particular metric, along most other metrics of this type--ie. static code metrics; including Lines-Of-Code (LOC); Function Points (FP); Interface Complexity (IF) etc,-- would be almost impossible to calculate to any degree of accuracy in any language that supports dynamic programming.

That is to say, any language that supports eval & bless; runtime creation of functions my $func = sub{...};; runtime modification of the symbol table *{"${module}::{$func}} =; introspection if( ref $arg ){...} & if( $arg->can( ... ) ) {...}; and probably others; is almost impossible to evaluate in these static terms.

If you try to do it simply by analysing the source code, you will completely miss all of the complexity that only comes into being at runtime. Even in pretty statitic langauges, like C, that support function pointers and dispatch tables, source code analysis is almost meaningless.

The only way to render these type of statistics vaguely meaningful and comparable is to totally hamstring the programmers to not using any language feature or construct that would defeat static source code analysis.

I once went through the exercise of taking a moderately complex, working system, that used function pointers and dispatch tables and re-writing it to remove these and a few other fairly everyday techniques that the 'Metrics guys' decried--mostly because their (very exspensive!), source code analysis software couldn't properly handle them.

The result was a system that was almost

  1. Twice as large;

    Every previously dynamic decision had to have all it's possible code paths laid out to static decisions. 60% of which would probably never be exercised, but they had to be there for 'completeness'.

  2. Much slower.

    Even simple constructs like (some) switch/case statements; functions with multiple (data-conditional)returns; even exception handling (of the setjump/longjump variety); were outlawed.

    Because 'they said', "the data-driven aspect of the control flow, meant the complexity and correctness of the running system was dependent upon the make-up and correctness of the data supplied". (That's a from-memory quote.).

    In other words, their software couldn't predict the path(s) of flow, so their metrics were useless.

  3. Involved a much higher degree of cut&paste "code reuse".

    Nearly identical functions 'xeroxed' with a different name--because it reduced the complexity number!

  4. Took nearly twice as long to refactor as the original did to code.

    And much functionality had to be 'deferred' along the way.

As with all such simple minded metrics systems, the original idea of providing for some means of measuring and comparing code quality, complexity and maintainability, is, in principle, a sound one.

The problem is that the result, is a metric that becomes self-serving.

  1. Programmer's work starts to be assessed on the basis of 'the numbers'--rather than their inventiveness, productivilty and thoroughness.
  2. User requirements start being rejected on the basis that it 'introduces too much complexity'--rather than on the usefulness and productivity gains that the feature would provide the users.
  3. Employer's start seeing the measurements as a way of reducing their maintainance and training bills--by employing cheaper maintainance programmers and providing less training.

    This is the most pernicious and debilitating effect.

    • Development team turnover starts to rise because they become sick of writing 'baby code'.
    • Maintainance programmer turnover rises because they are paid so little that the promise of a few pence more will take them away.

      Or the provision of some training that may lift them out of the maintainance role into the developer role.

      Or simply because when you pay peanuts.... Even with the best will in the world, not every person that adopts the job-title "programmer" is going to be any good at it.

      When you pay bottom dollar, the least-skilled practioners will tend to rotate amongst the employers within their area until such time as the pattern becomes obvious and they move onto the next area or re-invent themselves in some variation of the role.

I well remember the reactions of a few of the 'independant programmer assessments' that were made of the "reduced complexity system" that resulted from that exercise. Cheif among them were phrases like:

Don't misread me. I want code metrics. It has always seemed rediculous to me that a carpenter or metalworker can delegate a piece of work to an apprentice by drawing a sketch on the back of an envelope and writing a few numbers on it. The sketch doesn't need to be accurate, if the numbers (including tolorences) are.

But the equivalent task of delegation in software requires, two hours, an overhead projector, several white boards and still what you get back may be as much related to what you envisaged as a Mac truck is to a tricycle.

But imagine trying to measure the accuracy & productivity of a carpenter by measuring the length of his plane shavings or the volume of his sawdust; and then try and improve this by restricting him to overlap joints and nails because dovetails and screws are 'too complicated'.


Examine what is said, not who speaks.
"But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
"Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon