[SystemSafety] McCabe¹s cyclomatic complexity and accounting fraud

Steve Tockey Steve.Tockey at construx.com
Mon Apr 16 17:58:00 CEST 2018


Hi Les,
Apologies for the delayed reply. Got buried in the day job—sorry.

Thanks for the comments, I agree but want to add a few tidbits of my own.


You wrote:

“good software has much in common with good literature.”

That’s the observation that underlies Donald Knuth’s “Literate
Programming” book. A key quote from Knuth:

<quote>
Let us change our traditional attitude to the construction of programs.
Instead of imagining that our main task is to instruct a computer what to
do, let us concentrate rather on explaining to human beings what we want a
computer to do
</quote>



Then you wrote:

“It's worth pointing out that no experienced programmer believes
documentation - my scars are  deep. We find truth only in what is
executing.”

Well, this opens up a completely different proverbial can of worms, namely
a fundamental lack of professionalism. Imagine a ChemE, CivE, or any other
*real* engineer letting supporting documentation get out of synch with the
product. I’m back to my earlier observation that the software industry is
dominated by highly paid amateurs. That has got to change.


Later you wrote:

“I try to make my methods look like a coder's maintenance manual”

Yes. Knuth, revisited.



And then:

“Your appendix deals with static complexity only. Do you deal with
dynamic/temporal complexity elsewhere? This is of vital interest to me and
I'm sure many other developers.”

The intent of that appendix is to only deal with static, structural (I.e.,
syntactic) complexity. The rest of the book is intended to address
semantic complexity. As for dealing with dynamic/temporal complexity, that
depends on definitions of terms. State-event-transition type modeling is
dealt with in Chapter 10. On the other hand, treatment of concurrency and
multi-process, -thread synchronization is weak. If you have a good
reference on that topic, I’d like to hear about it.



Later on:

“From a programmer's point of view the motivation for high fan in is
maximum code reuse. The less code you have the less maintenance you need
to do. But lately I've been thinking that orthogonality is probably more
important, so I've been using more duplication to reduce the potential for
nasty side-effects - I sleep more soundly now.”

I would suggest that this is an issue of code semantics. Just because the
syntax of the function call matches the syntax of the called function
(that is, after all, the only thing the compiler and linker care about)
doesn’t mean that the functions are semantically compatible. That's what
the called function’s contract needs to make explicit. If the caller is
compatible with the called function’s semantic (Liskov Substitutable, to
be very specific) then the called function is adequate. If not, a
different function is needed.



Best,

— steve



-----Original Message-----
From: Les Chambers <les at chambers.com.au>
Date: Thursday, April 5, 2018 at 4:59 PM
To: Steve Tockey <Steve.Tockey at construx.com>,
"systemsafety at lists.techfak.uni-bielefeld.de"
<systemsafety at lists.techfak.uni-bielefeld.de>
Subject: RE: [SystemSafety]  McCabe¹s cyclomatic complexity and accounting
fraud

Hey Steve
I read your Appendix N: Software Structural Complexity Metrics (3
times).Thanks for drilling down on this subject. The industry needs it.

Reducing structural complexity has been a huge issue for me over the past
four years. Developing a complex cloud app it becomes a daily
consideration.
For me, the motivating factor for low complexity is understandability, both
in development and in maintenance.

All developers have this experience: Your code gets so complex you lose
track of the logic.  It literally gets away from you. It's six o'clock at
night and you've got a headache. You wake up in the morning can't
understand
what you wrote yesterday, so you throw it away and start again (that's if
you're a mature developer, we kill our children without remorse - the less
experienced punters go into nurture mode and soldier on, making it worse).
After all, good software has much in common with good literature. The mark
of a great author is not in what is published but what the author is
prepared to throw away. Ernest Hemingway used to invite people over for the
weekend to help him purge extraneous words. A candidate metric: SLOC kill
ratio?

So if it was up to me, this appendix would stress, in the first paragraph,
"high local structural complexity makes code inscrutable and because of
this
defects get injected". Write code you will understand in the morning and
two
years from now. Even more important, write code somebody else can
understand
two years from now.
It's worth pointing out that no experienced programmer believes
documentation - my scars are  deep. We find truth only in what is
executing.
We read code. If we cannot understand code we make mistakes - in
development
and maintenance. Ergo give us a break and reduce your structural
complexity.


I have a binary complexity metric. Turn on this music stream:
https://www.sbs.com.au/radio/chill
If you've got to turn it off to fully concentrate, the code you're reading
is too complex. Throw it away. Kill!
RE: fan out - the conclusions of your research citations are not
intuitively
obvious to me. I am a great fan of fan out. I have a simple rule of thumb:
make all individually testable code units as stupid (read simple) as
possible. This can result in high fan out - but I don't care. Reading a
five
line function is so relaxing, you can tap your foot to the music.

I try to make my methods look like a coder's maintenance manual - heavily
commented with complexity hidden in function calls and calls to other
methods. Any reader should be able to scan a method listing and get the
gist
of what its doing in one pass. Isn't this just good writing practice, even
in English? Tell them what you're going to tell them, tell them, tell them
what you told them (and in the code review ask them, "what did I say"). In
this way high fan out improves cognition. I don't understand how it is
increasing defect density -  according to the researchers. Is there an
explanation for this?

Your appendix deals with static complexity only. Do you deal with
dynamic/temporal complexity elsewhere? This is of vital interest to me and
I'm sure many other developers.

Cloud apps are heavily event driven and involve asynchronous remote
procedure calls (client/server) that put complexity through the roof.
Complexity in the time domain is a killer (kernel hackers have suffered
through this for decades). There can be massive structural complexity but
also temporal complexity where various operations can be performed on
various events and event arrival can be unpredictable.

To make things worse the behaviour of an app can be determined by front-end
code (JavaScript), individual browser rendering foibles, HTML and
accompanying cascading style Sheets (CSS), back end code (PHP) and system
product behaviour; e.g. MySQL, PHP interpreter configuration. Someone
should
write a book on that subject alone.

This has safety ramifications because this technology is currently being
used to fire hellfire missiles at Middle Eastern people from bunkers
outside
Las Vegas.

RE: fan in - I think it's worth drilling down on the impact of fan in on
orthogonality. 
Automobile Example: the same C function is used in the radio volume control
and the accelerator pedal signal conditioning. Then some eager beaver
optimises the function for smoother ramping of sound volume ignoring its
impact on vehicle acceleration. OOPS!

From a programmer's point of view the motivation for high fan in is maximum
code reuse. The less code you have the less maintenance you need to do. But
lately I've been thinking that orthogonality is probably more important, so
I've been using more duplication to reduce the potential for nasty
side-effects - I sleep more soundly now.

Hope these thoughts help.
Cheers 
Les

PS: !!! completeness defect, Appendix N, line 413 .  We are engineers
Steve.
We don't do ellipsis . Kill your child Steve. Kill!


-----Original Message-----
From: systemsafety
[mailto:systemsafety-bounces at lists.techfak.uni-bielefeld.de] On Behalf Of
Steve Tockey
Sent: Thursday, March 29, 2018 6:08 AM
To: Derek M Jones; systemsafety at lists.techfak.uni-bielefeld.de
Subject: Re: [SystemSafety] McCabe¹s cyclomatic complexity and accounting
fraud


All,
As I have said before,

³Software complexity is not a number, it is a vector²


Of course one can simply refactor code to reduce Cyclomatic Complexity and
yet the inherent complexity didn¹t go away. It just moved. But that¹s
kinda the whole point. Knowing that, can I call it, ³local complexities²
like Cyclomatic Complexity and Depth of Decision Nesting can be traded
for, can I call it, ³global complexities² like Fan Out, the developer¹s
goal should be to strike an appropriate balance between them. Not too much
local complexity balanced with not too much local complexity.

This is covered in a lot more detail in Appendix N of the manuscript for
my new book, available at:

https://www.dropbox.com/sh/jjjwmr3cpt4wgfc/AACSFjYD2p3PvcFzwFlb3S9Qa?dl=0




‹ steve




-----Original Message-----
From: systemsafety <systemsafety-bounces at lists.techfak.uni-bielefeld.de>
on behalf of Derek M Jones <derek at knosof.co.uk>
Organization: Knowledge Software, Ltd
Date: Wednesday, March 28, 2018 at 7:21 AM
To: "systemsafety at lists.techfak.uni-bielefeld.de"
<systemsafety at lists.techfak.uni-bielefeld.de>
Subject: Re: [SystemSafety] McCabe¹s cyclomatic complexity and accounting
fraud

Paul,

> There is the reported McCabe Complexity value for each function in a
> system. Yes, you can do things to reduce individual function complexity,
> and probably should. However, you then need to take the measure a step
> further. For every function that calls other functions, you have to sum
>the

I agree that the way to go is to measure a collection of functions
based on their caller/callee relationship.

This approach makes it much harder to commit accounting fraud and
might well produce more reproducible results.

> for the entire system on this basis. It becomes clear when you have too
>many
> functions with high complexity factors as it pushed up the average
>complexity
> value disproportionately. It still should not be the only measure though.

Where do the decisions in the code (that creates this 'complexity' come
from)?  The algorithm that is being implemented.

If the algorithm has lot of decision points, the code will contain
lots of decision points.  The measurement process needs to target the
algorithm first, and then compare the complexity of the algorithm with
the complexity of its implementation.  The code only needs looking at
if its complexity is much higher value than the algorithm.

-- 
Derek M. Jones           Software analysis
tel: +44 (0)1252 520667  blog:shape-of-code.coding-guidelines.com
_______________________________________________
The System Safety Mailing List
systemsafety at TechFak.Uni-Bielefeld.DE

_______________________________________________
The System Safety Mailing List
systemsafety at TechFak.Uni-Bielefeld.DE




More information about the systemsafety mailing list