On 12/31/12 1:39 PM, Marcus G. Daniels wrote:
Of course, there is rarely the time or incentive structure to do any of
this.  Productive programmers are the ones that get results and are fast
at fixing (and creating) bugs.  In critical systems, at least, that's
the wrong incentive structure.  In these situations, it's more important
to reward people that create tests, create internal proofs, and refactor
and simplify code.  Having very dense code that requires investment to
change is a good thing in these situations.

Programming for the broadcasting industry right now (where a few seconds downtime might cost millions of dollars), I especially liked your point, Marcus. I live within this tension every day, as I imagine so do to an even higher degree aircraft software designers, medical system designers, automotive software designers, and so on where many lives are at risk from a bug. Certainly the more unit tests that code has, the more "dense" the code might feel, as the more resistant to casual change it can become, even as one may be ever more assured that the code is probably doing what you expect most of the time. And the argument goes that such denseness in terms of unit tests may actually give you more confidence in refactoring. But I can't say I started out feeling or programming that way.

The movie "The Seven Samurai" begins with the villagers having a big conceptual problem. How do the agriculturalists know how to hire competent Samurai, not being Samurai themselves? The villagers would most likely be able to know the difference in a short time between an effective and ineffective farm hand they might hire (based on their agricultural domain knowledge) -- but what do farmers know about evaluating swordsmanship or military planning? Likewise, an end user may know lots about their problem domain, but how can users tell the difference between effective and ineffective coding in the short term? How can users distinguish between software that just barely works at handling current needs and, by contrast, software that could handle a broad variety of input data, which could be easily expandable, and which would detect through unit tests unintended consequences of coding changes? That is meant mostly rhetorically -- although maybe a more on-topic question for this list would be how do we create software systems that somehow help people more easily appreciate or understand or visualize that difference?

Unless you know what to look for (and even sometimes if you do), it is hard to tell whether a programmer spending a month or two refactoring or writing tests is making the system better, or making the system worse, or maybe just is not doing much at all. Even worse from a bean counter perspective, what about the programmer who claims to be spending time (weeks or months) just trying to *understand* what is going on? And then, what if after apparently doing nothing for weeks, the programmer then removes lots of code? How does one measure that level of apparent non-productivity or even negative-productivity? A related bit of history:
  http://c2.com/cgi/wiki?NegativeLinesOfCode
"A division of AppleComputer started having developers report LinesOfCode written as a ProductivityMetric?. The guru, BillAtkinson, happened to be refactoring and tuning a graphics library at the time, and ended up with a six-fold speedup and a much smaller library. When asked to fill in the form, he wrote in NegativeLinesOfCode. Management got the point and stopped using those forms soon afterwards."

If there is a systematic answer, part of it might be in having lots of different sorts of metrics for code, like in the direction of projects like "Sonar". I don't see Sonar mentioned on this list, at least in the past six or so years. Here is a link:
  http://www.sonarsource.org/
"Sonar is an open platform to manage code quality. As such, it covers the 7 axes of code quality: Architecture & Design, Comments, Coding rules, Potential bugs, Complexity, Duplications, and Unit tests"

We tend to get what we measure. So, are these the sorts of things new computing efforts should be measuring?

Obviously, users can generally see the value of new functionality, especially if they asked for it. And thus there is this tension between infrastructure and functionality. This tension is especially strong in the context of "black swan" situations where chances are some rare thing will never happen, and if it does, someone else will be maintaining the code by then. How does one create incentives (and supporting metrics) related to that? In practice, this tension may sometimes get resolved by spending some time on refactoring and tests that the user will not appreciate directly and some time of obvious enhancements users will appreciate. Of course, this will make the enhancements seem to take longer than they might otherwise in the short term. And it can be an organizational and personal challenge to interleave the two areas of work (infrastructure and functionality) so the users stay happy enough. Yet, I might argue, if you don't do the two in parallel, you may find you are not creating either the needed infrastructure or the needed code.

"Agile" methods embrace the idea of coding for obvious functionality, saying "You're not going to need it". But agile methods may also be more appropriate in some situations than others. And agile methods do also tend to celebrate and insist on refactoring and testing on the way to creating new functionality, which when you think about it is an odd-seeming way of addressing your point -- by a sort of "cultural" approach. In that sense, Agile methods start with the best practices of testing and refactoring as givens in an programming culture, and then measures progress in terms of function points. But there is always going to be the pressure to focus more on the function points and less on the other things. And that might be where tools like Sonar help keep teams from letting maintainability slide in the quest for new function points.

Maybe we need a language where code just won't compile unless it has tests written for it in advance? :-) Was Eiffel heading that way with "Design by Contract"? Or maybe we need to have more projects using tools like Sonar, and write even better such tools, as well as better languages to use with them? The message passing paradigm in Smalltalk (making proxying and mocking easier) along with other aspects like dynamic strong typing, means Smalltalk historically lent itself to creating better tools and tests. Although there is still a tension in that statically-typed systems also made some other sorts of reasoning about programs easier to do. (Not to get into that discussion, which has been hashed out on this list and in many other places before.)

Like Fred Brooks said in 1986:
  http://en.wikipedia.org/wiki/No_Silver_Bullet

Or, as Kyle Wilson said in 2007:
  http://gamearchitect.net/Articles/SoftwareIsHard.html

Still, we'd probably get software that was both more reliable and more maintainable (as well as more fun to work with) if we just more commonly used computing ideas (like message passing) that have been known for decades. Or, for another example, Smalltalk's keyword syntax generally makes for much more readable programs. Or for yet another example, Forth could support a multi-user system doing real-time data collection, word processing, and data analysis using just 32K bytes and a single 1 Mhz processor, whereas many systems today struggle to be responsive for a single user or single application when they have 32GB and 8 X 3 Ghz processors. Indeed, do we need to go "Back to the future" again? :-)

--Paul Fernhout
http://www.pdfernhout.net/
====
The biggest challenge of the 21st century is the irony of technologies of abundance in the hands of those thinking in terms of scarcity.
_______________________________________________
fonc mailing list
fonc@vpri.org
http://vpri.org/mailman/listinfo/fonc

Reply via email to