One of the axioms of software quality is that bugs are highly gregarious. When I say bugs are gregarious, I don’t mean they like to go out to cocktail parties to schmooze and flirt with the interns. I mean that they tend to hang out in the same parts of the codebase. In many cases it is within 20% of the code where 80% of the problems arise (Pareto principle applies). This is important to consider, because it is this code that can benefit most from refactoring and where the developer should aim to get 100% coverage in unit tests.

I have been campaigning heavily in my company to ensure that a Master Test Plan (MTP) is prepared at the start of every project. A key element of an MTP is to identify the highest risks to quality and introduce risk-based testing contingencies to manage those risks. The problem is: how do I identify the risks? I think the answer to this question is to ask the more telling question: in what parts of the system does the highest complexity lie?

Before I bought my current car, I had a very sporty Mitsubishi Eclipse with all the options: power everything. I had nothing but problems with that car, culminating in the coup d’grace when it was laid up for a month outside my house in Washington DC only to suffer the ultimate indignity of having a colony of rats move in under the hood and chew all the wiring. Everything was gone: power steering, lights… I couldn’t even wind the bloody windows down! So when I traded it in for a less glamorous Ford Focus I deliberately turned down the options. I remembered why my Father hated automatic transmissions, because they are too complex to fix. The more there is, there more there is to go wrong. I have learned that my eternal nemesis, entropy, will always win in the end, the best I can do is delay it.

When it comes to software there is a very strong positive correlation between the amount of complexity in a given unit of code and the number of defects that are likely to manifest.
Wouldn’t it be nice if we could analyze our code somehow measure how complex each component is? That would give us a great deal of predictive power for unit tests, refactoring efforts and test planning. It would also identify application features that may be so expensive to maintain that they are not worth inclusion, leading to a more stable and reliable user experience.

The good news is that such code metrics exist. They have been around for at least 30 years and been so successful that engineers have calibrated them to measures of risk. Static code analysis tools have been developed to scan source code files and produce nice shiny reports useful for decision support and business reporting purposes. The bad news is there are no such tools for PHP, at least none that I can find. Most static code analysis tools are targeted to C/C++ and Java, with several emerging for C# / .NET. There are even a scattering of projects for Python and Ruby. For PHP, nada. This exposes one of the multiple limitations of PHP.

Given the high adoption of PHP compared to Python and Ruby, even in large enterprise environments, why is it that PHP does not have such tools? I think the answer lies in the fact that the majority of people who use PHP as a programming tool are not system developers and have minimal exposure to software engineering principles in general. PHP developers are for the most part web developers, due in large part to PHP’s origins as a domain specific language. Sure there are PHP binding to GTK, but no GUI applications of significance have been built in PHP.

Writing a source code scanner is not something your typical PHP web developer would know how to do. If they attempted it, they would probably try using regular expressions in a PHP script, that ultimately would be a fragile and unreliable solution. You really have to analyze the parse tree itself, not the base source code.

Analyzing the PHP parse tree sounds a little scary. However, it turns out to be fairly trivial to access the parse tree in an XML format using the Parse_Tree extension based on the Yacc extension to XML (YAXX). Using this extension you don’t even need to implement a scanner yourself, all you need is an XML parser which is something a more advanced PHP web developer has the capabilities and comprehension to attempt.

UPDATE: In the middle of writing this entry I came across Sebastian Bergmann’s PHPUnit and Software Metrics announcement of new feature support of software metrics in the forthcoming PHPUnit 3.2. This is excellent news. Not only does it support almost all the LOC metrics (of relatively little value with regard to quality, more useful for estimating as used within COCOMO), but one of the most useful metrics I know: cyclomatic complexity. It will provide a list of every class and function with a calculation of it’s cyclomatic complexity (basically a measure of the number of possible unique execution paths and states). However, although I haven’t looked at the code, I suspect that they are not calculating the cyclomatic complexity from the parse tree. Regardless, it’s a great start.

Two other metrics supported by PHPUnit worth looking at:

It is futile to attempt any quality improvement efforts without some form of objective measures with which to work. Static code analysis provides important key metrics that, combined with defect rates etc., provide good baselines for improving code quality and identifying problems early (essential to any quality practice).

Well that’s PHP software quality taken care of. I’m going outside now to check my car for rats.

I was rereading Paul Graham’s article The Hundred-Year Language and my imagination ran away with me. I have always had a love and facination for linguistics in general, and computer language in particular. One thing Graham wrote struck a chord with me:

One way to design a language is to just write down the program you’d like to be able to write, regardless of whether there is a compiler that can translate it or hardware that can run it. When you do this you can assume unlimited resources. It seems like we ought to be able to imagine unlimited resources as well today as in a hundred years.

After reading this I made my way to the proverbial ‘potting shed’ to start tinkering. There are a few things I’m looking for in a programming language and they are:

  • Clean syntax - avoid excessive use of punctuation and symbols — other than exclamation marks because research shows women use them more than men, and I want to be where the chicks are. No ‘nail-clippings in bowls of oatmeal’ need apply!
  • Optimized for human-readability — well implemented solutions should be self-documenting and, dare I say it? … prosaic
  • Follows the Principle of Least Astonishment — the interface (syntax) should be consistent and predictable. Perl is delightfully expressive, but there is no room for poetry when you are trying to get the job done
  • Syntactic sugar is OK! — I have a sweet tooth, and the fact is C could just as easily be condemned as syntactic sugar sprinkled over Assembly. The very principle of HLL is packed full of carbs
  • Should be machine-readable — sufficient to allow easy development of refactoring and code analysis tools. It has been said that the only thing that can parse Perl is Perl (not so true of Perl 6) and this has limited the availability of such development tools
  • Whitespace should not be meaningful — Sorry Python, but though whitespace is essential for good readability my code should compile without having to worry about it
  • Dynamically typed – because I’m lazy and only want to worry about data integrity issues when it is meaningful within the problem domain
  • Support lambdas — LISP has bestowed so many boons upon us, the lambda function being one of the most important, though under-utilized
  • Concretises abstractions — Computers and data structures are abstract enough, there’s no need for a general purpose programming language to litter its symbol tables with mathematical abstractions. Give the non-mathematicians a break!
  • Protects the programmer — from their own human fallibility. C has left us with the assignment/equality error all the way through to Ruby, so can we fix this already?!
  • Friendliness — can we have our reserved words make us smile a little… just a little? Why do all our computer languages sound so pretentious?

Read the rest of this entry »

You just can’t find good help these days. I have been burned by a series of poor hires that have resulted in numerous project overruns, unhappy clients and, more seriously, poorly implemented and unmaintainable code. One particularly painful example of code abuse involved a contractor hired to maintain a social networking and collaboration-based website that I had developed. They implemented almost every feature in such a way that it necessitated a complete rewrite of at least 5 features. Most of these features had crept in under the radar on our backlog and so I didn’t find them until we started upgrading the system ready for our next major phase development.

The problem is all of these poor hires seemed smart in the interview, the code samples seemed fine; nothing genius, but more than acceptable. For this reason I have been looking for ways to improve the screening of candidates. There are interview coding tests like the FizzBuzz test.

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz.” For numbers which are multiples of both three and five print “FizzBuzz.”

Such tests are all well and good, but as Paul Graham explores in his essay Great Hackers there really is no objective way of assessing how good a programmer is until you have actually worked with them and seen how they approach and solve real-world problems. Their code samples may look great, but such samples don’t tell you how long it took them to write the code you are reviewing. FizzBuzz tests are a little better because you see them solve problems in real time. However, I would never use FizzBuzz as quoted above, because the example is too well known already and people are already learning the solution in multiple languages simply to prepare for it should it come up in an interview.

An interesting approach that companies like Google and Facebook are adopting is to publish standardized aptitude tests like the Google Labs Aptitude Test or coding challenges. This may work for ‘cool’ companies in the Web 2.0 cutting edge, but it’s not feasible for small but growing consulting companies like ours.

In a labor market where 199 out of 200 job applicants are unable to solve even the most trivial coding challenge like the FizzBuzz test what are small companies to do? The fact is good developers are not looking for work or sending out their resumes (I haven’t updated my resume in 8 years). The one’s applying to the job ads are the same 199 out of 200 that have already been rejected by everyone else, and who can barely write their name let alone good code.

The other 0.5% are not guaranteed to be good either. We are facing the same problem we had with the original dotcom bubble now that Web 2.0 startups are becoming hot. VC money can afford to trawl the labor pool for the better developers, leaving very slim pickings for those of us on the bottom of the food chain.

The only solution is to cultivate talent, find competent and bright non-programmers or developers early in their careers then seriously mentor and groom them. We have done this before and there are risks if you don’t make the investment in their training and professional development. It’s either that or outsource it all to the kids in the Malaysian sweatshops. They will be happy of the work, anything to break the tedium of assembling shoes for Nike.