PragPub 2011-11: Issue #29

Table of Contents

Features

Inside iOS 5

by Bill Dudney

Bill takes us into the heart of iOS 5, introducing some powerful new APIs that have not received as much exposure as the APIs behind the new user features.

Scala for the Intrigued

by Venkat Subramaniam

In this third installment of his series on the Scala programming language, Venkat shows how Scala’s OO purity leads to simple, elegant code.

Test-Driven Development

by Jeff Langr

Jeff has written the case for TDD for managers. You may want to pass this article along to the manager you think needs to read it. Or study the article for when you need to make the case to a manager.

Self-Inflicted Scope Creep

by Jonathan Rasmusson

The client didn’t ask for anything new. Why has the project grown?

Root Cause Analysis from Long Ago

by Brian Tarbox

Cleaning out his basement, Brian comes across a document that shows how little programming has changed in 23 years.

When Did That Happen?

by Dan Wohlbruck

One person predicted the coming of computer viruses. He also invented them.

Departments

Up Front

by Michael Swaine

If you ever wanted to write a book, this is the month to start, and we’re ready to help. It’s our third annual PragProWriMo writing month.

Choice Bits

Drinking from the Twitter firehose.

Meet the Team

Meet Janet Furlow, Pragmatic Bookshelf’s Production Manager.

Calendar

Author sightings, upcoming conferences, and other events of note.

Shady Illuminations

by John Shade

John has seen the future, and it’s a roach motel.

But Wait, There’s More...

Coming attractions and where to go from here.

Except where otherwise indicated, entire contents copyright © 2011 The Pragmatic Programmers.

Feel free to distribute this magazine (in whole, and for free) to anyone you want. However, you may not sell this magazine or its content, nor extract and use more than a paragraph of content in some other publication without our permission.

Published monthly in PDF, mobi, and epub formats by The Pragmatic Programmers, LLC, Dallas, TX, and Raleigh, NC. E-Mail support@pragprog.com, phone +1-800-699-7764. The editor is Michael Swaine (mailto:michael@pragprog.com). Visit us at http://pragprog.com

ISSN: 1948-3562

Up Front

PragProWriMo and More

by Michael Swaine

If you ever wanted to write a book, this is the month to start, and we’re ready to help. It’s our third annual PragProWriMo writing month.

We have a lot going on this month: Six feature articles, a staff profile, calendar, John Shade, and our November writing blitz.

Bill Dudney shares some cool features of iOS 5 that you probably haven’t head about in general tech press coverage, and that can help you develop cool new apps. Jonathan Rasmusson tells you how to avoid shooting yourself in the foot with self-inflicted scope creep. Dan Wohlbruck recounts the story of the first computer virus. Venkat Subramaniam is back with another in his series on the Scala language. Jeff Langr gives you all the arguments you need to convince managers of the need for test-driven development. John Shade opines that you have to be light on your feet to play in the clouds. And Brian Tarbox finds some poignant documentation while cleaning out his basement.

And then there’s PragProWriMo.

A Month for Writers

This month, we’re holding our third annual tech book writing month, piggybacking on the idea of National Novel Writing Month (NaNoWriMo). For you Pragmatic Bookshelf authors, this will be a great chance to make lots of headway on your books. If you’re just starting your book, a sprint in November will get you heading toward critical mass. If you’re almost done, November could be the final push you need to finish your book. If you aren’t (yet) writing a book for us, we have advice for you, too. And a supportive community of other writers. And answers to your questions. And the motivation of weekly wordcount checkins, if you want that.

Your primary point of connnection should be the PragProWriMo 2011 Writing Forum on our site. I’d also recommend that you check out my blog; I’m going to try to post useful writing information there every day in November. And you should follow our PragProWriMo twitter account. It will be tweeting helpful and inspiring bits of writing wisdom.

We’re looking forward to plenty of book writing action in November!

Choice Bits

Recruiters Bad, Siri Good.

Drinking from the Twitter firehose.

What’s Hot

Top-Ten lists are passé—ours goes to 11. These are the top titles that folks are interested in currently, along with their rank from last month. This is based solely on direct sales from our online store.

1^ | NEW | Rails Recipes
2^ | NEW | Build Awesome Command-Line Applications in Ruby
3v | 1 | Agile Web Development with Rails
4^ | NEW | Programming Your Home
5^ | 6 | The Cucumber Book
6^ | 7 | Programming Ruby 1.9
7v | 5 | Web Development Recipes
8v | 2 | Technical Blogging
9v | 4 | CoffeeScript
10 | 10 | The RSpec Book
11v | 3 | Programming Clojure

Recruiters Bad

Never invite the scorn of DHH.

Recruiter message to inventor of Rails: How many years of Rails experience do you have? DHH: ALL OF THEM. — @Snugug

While not as entertaining as groupon’s recruiter trying to nab dhh, I get pinged about qtp gigs as least once a month. #idiots — @adamgoucher

Recruiter e-mail: “Must have more than 6 years of experience building Mac OS X software on Intel.” Intel transition was announced mid-2005. — @invalidname

“Join this Startup that wants to improve remote collaboration with your team. Must relocate to SF.” — @bphogan

Pretty much every public Ruby list I’m on is 90% chatter about jobs and recruiter hating. — @mperham

As a recruiter one of my primary skills is erasing the conference room white board before the next interview starts. — @okkfan

Siri Good

As predicted 24 years ago.

Gave myself a nickname in Contacts. Now Siri says “Hello, Sweetie.” — @leahkiem

I said goodnight to Siri last night, and it said goodnight back. It was as comforting as it was unutterably sad. — @BinaryDad

I’m afraid that in about 8 years there are going to be a bunch of second-graders named Siri. — @aspaul

Empirical date indicates that when you set Siri to British English, you have to say al-you-minium instead of aloo-minim. — @therealadam

This Twitter investor has outsourced all replies to Siri. Related: There are 3 restaurants near you and it’s currently 57 and overcast. — @sacca

I can’t believe it took so many days for someone to say, “Siri, capture Gaddafi.” — @stemcd

Short-Short Stories and Average-sized Writers

Not NaNo fiction, but maybe Nano fiction.

We were celebrating the merchandise, shop shelves, assistants in costume. We’d forgotten what Halloween was truly about—torture and death. — @DeadEndFiction

I woke to a pack of wolves in the kitchen, howling at the fridge. I fed them frozen waffles and one by one they turned back into my children. — @VeryShortStory

Most interesting question I got from a 5th grader today when talking about being a writer: “Is it illegal to jailbreak your iPod?” Attaboy. — @BodyofBreen

Attn World Fantasy Con people. My reading (2:30-3:30) has just moved from Town & Country Room to the Regency Room. Wherever that is. — @neilhimself

@neilhimself It sounds like you need to change your speaking outfit from riding gear to something involving a tailcoat and cravat. — @Ihnatko

Once they were gone, they were gone forever. A few people disappeared first. Th n it was let rs that w nt mis ing. Finally, it was entire — @DeadEndFiction

The Fix Isn’t In Right Now, Would You Like to Leave a Bug Report?

Don’t use Duct Tape; Velcro Looks Better (from New Programmer’s Survival Manual). — @PragmaticAndy

I’ve tried everything else on this code, so here goes: Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtan. Iä! Iä! Cthulhu fhtagn! — @gvwilson

There’s nothing wrong with New York that wouldn’t be fixed by banning Budweiser & PBR and importing some proper British Real Ale. #gonenative — @rit

You Might as Well

Nobody cares if you’re miserable so you might as well be happy. — @GianNJuice

“Life’s but short. You might as well be amusing.” -Coco Chanel — @IDstudentjob

“You might as well live.” -Dorothy Parker — @WEPromote

You might as well be yourself, because nobody else will do it for you. — @clarkware

If you have a protected Twitter account you might as well stay on Facebook. — @SteveO_MTV

What Twitter Is For

A million guys walk in to a Silicon Valley bar. None of them buy anything. The bar is declared a rousing success. — @dwlz

If you can make a tablet out of an ice cream sandwich, you have my attention. — @ryanirelan

I always knew they would try to turn me into a number. I never thought it would be a percentage. — @benrady

If you don't like writing about the weather around here, just wait until the next paragraph. — @FakeAPStylebook

In case you missed it last night—we can now sent your ebooks straight to your Dropbox. Great for iXxx and Android. — @pragdave

We are delighted to announce that Rachel Davies (@rachelcdavies) is joining us as director of IL Europe. — @IndustrialLogic

SPOILER ALERT: Twitter is for spoilers. — @jfricker

Who Are Those Guys?

This month we galled the kibes of Chris Adamson, BinaryDad, Chris Breen, Mike Clark, DeadEndFiction, Fake AP Stylebook, Kevin Fanning, John Fricker, Neil Gaiman, Adam Goucher, Brian P. Hogan, Andy Hunt, Andy Ihnatko, IndonesianStudentJob, Industrial Logic, Ryan Irelan, Adam Keys, Leah Kiem, Bruce Lee, Dan Loewenherz, Brendan W. McAdams, Stephen McDonald, Not Steve-O, A.S. Paul, Mike Perham, Ben Rady, Sam Richard, Chris Sacca, Dave Thomas, Very Short Story, WhisperingEnergy, and Greg Wilson. You can follow us at www.twitter.com/pragpub.

Meet the Team

Janet Furlow

Each month we profile a member of the Pragmatic Bookshelf team. This month it’s Janet Furlow, our indispensable Production Manager. Janet juggles a whole family of cats—authors, editors, copy editors, indexers, layout folks, printers, distributors, not to mention Andy and Dave. Without her we’d never get a book out the door.

Janet Furlow, Production Manager

Janet has been working with the Prags since 2007. She met Dave Thomas in 2006 when their kids were in Cub Scouts together. Dave’s wife, Juliet, saw how amazing Janet was at organizing and herding the den, and suggested that if she could keep 6-year-olds in line, she might stand a chance of doing the same with Dave and Andy. “At the time,” Janet says, “I was a stay-at-home mom. I had been out of the workforce since my first son was born, and I was hoping for a job that was flexible enough to let me ‘do it all.’ I wanted to be at home when my boys got home from school and be involved in their activities. This job is the best of both worlds.”

Since then she’s gone from knowing nothing about publishing (which is where Andy and Dave started) to being the totally indispensable center of our entire production process.

“My role has really grown over the years. I manage the production schedule, working with the editors and our production team to get titles announced to the public and moved through the indexing, copy edit, layout, and printing processes. This also involves feeding a couple of databases—one for our store web site and one for public online stores. Then there’s the final prep work on titles going into our beta program, managing our reprint schedule, and various administrative tasks, such as author contracts and registering new titles with the Library of Congress for copyrights. I've always got something going on.

“I had someone say to me once, ‘Wow! You've got the best job in the world!’ She was right.

“In my personal time, I’m totally hooked on Sudoku and Spider Solitaire. But my favorite time is spent watching my two sons play ice hockey.”

Email: janet@pragprog.com

Inside iOS 5

Three New Features That Will Help You Build Better Apps

by Bill Dudney

Bill takes us into the heart of iOS 5, introducing some powerful new APIs that have not received as much exposure as the APIs behind the new user features.

iOS 5 is an amazing release for users, with tons of great features, like Wireless Updating, Notification Center, Newsstand, and iMessage. Of course you’ve heard about Siri, the virtual assistant built into the new iPhone 4S. Even if you don’t see Siri fitting into your daily work flow, it is definitely worth checking out.

But this latest release of iOS is even more significant for developers. With the introduction of iOS 5 we get access to some really powerful features of the SDK. I’d like to take you through three of the new APIs that have not received as much exposure as the APIs directly tied to the user features. Two of these are serious infrastructure to help us make better apps, while the third is just so much fun it’s hard not to talk about.

JavaScript Object Notation Serialization

If you have written an application that interfaces with a web service you have no doubt had to make the decision whether to use XML or JSON. XML has been fully supported by iOS since version 2.0. Up until this release, though, we had to turn to third party and open source to parse JSON. Well, no longer. In iOS 5 we have the NSJSONSerialization to make parsing JSON a one-line exercise.

Here is some sample JSON for a photograph:

| {
| "taken": "2011/07/13",
| "width": "3072",
| "height": "2304",
| "latitude": "39.52",
| "longitude": "-106.05",
| "url": "http://mypictures.com/12345.png"
| }

Parsing this JSON is really simple. Here is the code:

| NSError *error = nil;
| NSData *data = [NSData dataWithContentsOfURL:webServiceURL];
| NSDictionary *photo = [NSJSONSerialization
| JSONObjectWithData:data
| options:NSJSONReadingMutableLeaves
| error:&amp;error];
| NSNumber *width = [photo objectForKey:@"width"];
| NSNumber *height = [photo objectForKey:@"height"];

That’s it. No library to download, no build settings to configure, just code and go. The JSONOBjectWithData:options:error: method turns the data argument into an NSDictionary or an NSArray depending on the root of the JSON file. In our case it’s a dictionary. Once parsed, the data is available as an object for us to interact with.

NSJSONSerialization can parse data in memory, as we have done here, as well as a stream. Using a stream can be very important for large data sets. Instead of having to pull all the content into memory at once, you can process the data in smaller chunks. Your maximum memory usage could be much smaller using the stream technique. In either case it’s just as easy to parse. Here is the code to load via a stream, which is more or less the same as before. The only change is to use the JSONOBjectWithStream: variant of the method.

| NSError *error = nil;
| NSStream *stream = [self getMyStream];
| NSDictionary *photo = [NSJSONSerialization
| JSONObjectWithStream:stream
| options:NSJSONReadingMutableLeaves
| error:&amp;error];
| NSNumber *width = [photo objectForKey:@"width"];
| NSNumber *height = [photo objectForKey:@"height"];

The JSON support in iOS goes even deeper: we can use it to produce JSON data. This makes posting data to web services via JSON just as easy as consuming JSON.

Automatic Reference Counting (ARC)

One of the more difficult challenges for developers moving from garbage-collected languages to Objective-C is understanding how memory management works. While garbage collection has been available on OS X for some time, Apple has resisted bringing it to iOS because of the power usage profile and the realtime nature of a mobile device. But with the release of iOS 5, Apple has provided automatic memory management without the adverse performance characteristics of a garbage collector.

ARC works by formalizing a set of rules that have been around on the Mac since the advent of OS X. Every time you want to hold onto an object you send it the retain message. When you are done with the object, you send release. These two calls have to be balanced. For every retain you must send release, or the object is leaked. Too much leaked memory and the OS will kill an app.

When iOS 4 was released, Apple included a tool called the Static Analyzer that analyzed code and pointed out potential leaks. Some clever soul asked the question, “If it can tell me about where a leak is going to happen, why doesn’t it just fix it for me?” That is basically what Apple delivered in ARC.

In addition to managing the retain-and-release memory management of our objects, ARC adds a new concept called “zeroing weak references.” Weak references nil out when they are no longer referenced. Since messages to nil are no-ops in Objective-C, we get a huge safety bonus. With this new feature, our weak references will no longer point to dangling pointers, but will instead be cleaned up for us automatically.

To use ARC on a new project, just check the box for “Use Automatic Reference Counting” in the new project panel, which turns on all the features of ARC for your entire project.

For existing projects, you can test the waters by turning on ARC one file at a time via the -fobjc-arc flag. Or, if you are ready to take the plunge, you can use the “Edit->Refactor->Convert to Objective-C ARC...” menu item built into Xcode to transform an existing project and its code over to ARC.

Core Foundation and ARC

There are a few small gotchas for large existing projects that will likely require some tweaking if you use Core Foundation objects and toll-free bridging. With ARC you must tell the compiler what you intend to do with the Core Foundation object. If you don’t, you get a compiler error. Here is an example that shows the error:

| NSDictionary *values =
| [NSDictionary dictionaryWithObject:@"object" forKey:@"key"];
| CFDictionaryRef dictionary = (CFDictionaryRef)values;
| SomeFunctionCallThatNeesACFDictionary(dictionary);

When ARC sees this code, it is unsure what the intent is for the CFDictionaryRef pointer and can’t know if it will be safe to release the values dictionary when it normally would. So, it insists that you tell it. You can specify one of two intents. Say you only want to use this dictionary as a CFDictionaryRef in this scope and won’t be keeping it around after that. In this case, use the __bridge modifier in the cast, like this:

| NSDictionary *values =
| [NSDictionary dictionaryWithObject:@"object" forKey:@"key"];
| CFDictionaryRef dictionary = (__bridge CFDictionaryRef)values;
| SomeFunctionCallThatNeesACFDictionary(dictionary);

If, on the other hand, you want to keep the dictionary around for a longer time, you need to tell ARC that. Use the __bridge_retained modifier and ARC will add a retain to the Core Foundation (CF) object. That ensures that the CF object will remain until it is explicitly released with the CFRelease function. Of course, that means you must explicitly release values or it will be leaked.

If you are casting from a CF type to an Objective-C object you can tell ARC that you intend the Objective-C version of the object to be the real owner of the pointer. Use __bridge_transfer in that case, like this:

| CFDataRef dataRef = CFDataCreate(NULL, longStringOfBytes, 0);
| NSData *data = (__bridge_transfer NSData *)dataRef;
| [someObject thatNeedsAnNSData:data];

Now ARC has taken over the retain/release responsibility for the data object, and the CF object will be released for you. If you don’t use CF objects then you don’t have to worry about these gotchas.

ARC is a fantastic new feature that has not gotten nearly the exposure that it deserves. It will greatly simplify the lives of current developers and smooth the learning curve for developers new to the platform. If you are starting a new project, definitely give ARC a go. It’s fantastic!

Core Image and Face Detection

The last feature I want to describe, Core Image and Face Detection, is just so cool it’s hard not to laugh out loud the first time you see it in practice. If you are a registered iOS developer it’s worth pushing the sample out to your device and playing with it. Enough talk, let’s get building. This example has three major features: choose or take a photo, detect facial features, and draw shapes around the detected features.

To choose or take a photo on iOS, you use the UIImagePickerController view controller. The picker controller is a view controller, just like any other view controller on iOS. We create it, configure it, then present it. To configure it we ask what features are available (is there a camera, etc.) and then configure our UI accordingly. If the camera is present, we display an action sheet to let the users choose to take a photo or choose a photo. If there is no camera, then we display the user’s photo library. The details of how the action sheet and picker are displayed are in the sample code, so go take a look there if you need to brush up on using either of those classes.

Once the photo is chosen or taken, the image picker gives us the photo via the imagePickerController:didFinishPickingMediaWithInfo: delegate callback method. In this method we’ll grab the selected image and do the face detection. First, we get the image:

| self.image =
| [info objectForKey:UIImagePickerControllerOriginalImage];

The info dictionary passed in has a bunch of interesting keys. The documentation lists them all.

Now that we have an image, we need to transform it into a format that Core Image can work with. Fortunately it’s really easy to do that; we just create a CIImage with the image we just got out of the info dictionary, like this:

| NSNumber *orientation = [NSNumber numberWithInt:
| [self.image imageOrientation]];
| NSDictionary *imageOptions =
| [NSDictionary dictionaryWithObject:orientation
| forKey:CIDetectorImageOrientation];
| CIImage *ciimage = [CIImage imageWithCGImage:[self.image CGImage]
| options:imageOptions];

We have to pass along the orientation, because CGImage does not contain the orientation information and Core Image needs to know that to recognize faces.

Next, we create a feature detector to scan the image for faces. Here is the code:

| NSDictionary *detectorOptions =
| [NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh
| forKey:CIDetectorAccuracy];
| CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
| context:nil
| options:detectorOptions];

The first argument must always be CIDetectorTypeFace. However, since we have a parameter here we can hope that someday we’ll be able to scan for other items in images as easily as we can scan for faces now. The list of options takes only this one key, CIDetectorAccuracy and one of two values CIDetectorAccuracyHigh, as we have used here, or CIDetectorAccuracyLow. These two values allow us to trade off between speed and accuracy. The higher the accuracy the longer it can take to do the detection work.

The last step is to grab the features from the detector, like this:

self.features = [detector featuresInImage:ciimage];

Each feature that is returned is an instance of CIFaceFeature, one instance for each detected face. The face features have four properties we are interested in: the overall rectangle containing the face, the location of the right eye, the left eye, and the mouth. We take each feature and draw a shape around that feature. I’ve provided a screen shot of William Shakespeare’s face with the highlighted shapes drawn.

While this is a fun but silly use of the face detection feature, it can be combined with other filters to do some really amazing stuff. For example, if you are upgraded to Lion on your Mac, fire up Photo Booth and take a look at any of the first set of features. My kids are especially fond of Frog. This set of effects is using the face and facial feature detection to determine where to place the effect. Frog uses the eyes, while Nose Twirl uses both eyes and mouth to approximate where your nose is. While Photo Booth is often silly, this feature is used to add features to iMovie that are seriously useful. Finding faces in a movie makes it possible to do the automated trailer generation.

iOS 5 is a rich and powerful release. Apple has given us some serious tools to make us more productive as well as some really fun features to inspire our creative side. Now that you’ve seen a bit of what’s in iOS 5, I hope you’ll go out and build something beautiful!

Bill Dudney is co-author of iPhone SDK Development. He is a software developer and entrepreneur currently building software for the Mac. Bill started his computing career on a NeXT cube with a magneto-optical drive running NeXTStep 0.9. Over the years Bill migrated into the Java world where he worked for years on building cool enterprise software. But he never forgot his roots and how much fun it was to write software that did cool things for normal people. Bill is back to AppKit to stay. You can follow him on his blog.

Scala for the Intrigued

Cute Classes and Pure OO

by Venkat Subramaniam

Venkat wrote the book on Scala. This third installment of his series on Scala shows how Scala’s OO purity leads to simple, elegant code.

In this third part of the series we will explore the elegance and purity of the OO side of Scala.

Writing classes is one of the most common tasks that every Java programmer does. Let’s write a class Car in Java:

| public class Car {
| private final int year;
| private int miles;
| public int getYear() { return year; }
| public int getMiles() { return miles; }
| public void setMiles(int theMiles) { miles = theMiles; }
| public Car(int theYear, int theMiles) {
| year = theYear;
| miles = theMiles;
| }
| }

All we said in the above code was that we’d like to initialize a Car with a read-only property year and a read-write property miles. However, it took quite a few keystrokes to achieve that.

You may hear some Java programmers protest “But I never write those myself, I only declare the fields and with a right click, my IDE vomits the rest of the code.”

We don’t need that in Scala. Let’s write the above Car class in Scala. Go ahead, type this into a Car.scala file.

class Car(val year : Int, var miles : Int)

That’s it.

You can declare classes private if you like, but if you leave out the declaration, it defaults to the most common scenario—public class.

With that concise declaration, you made year a read-only field with a getter (and no setter). The miles has both a getter and a setter since you used var instead of val to define it.

Hey, but what about a constructor? In Scala, when you define a class you’re writing the primary constructor. Any code you directly place into the class becomes part of this constructor. Any fields and methods you define become part of the class.

You can write other constructors, called auxiliary constructors. Scala enforces that the auxiliary constructors call the primary constructor and only the primary constructor is allowed to pass data to the base (super). This helps reduce accidental code duplication among constructors and tightly manages the instantiation of the base and the derived parts of instances.

So the constructor is also done when you write the class. You may wonder what you will now do with all your free time. Go home, you don’t have to write redundant code in a smart language.

The getter/setters created by default do not follow the JavaBean convention. If you’d like, ask Scala to follow that convention using the @BeanProperty annotation:

import scala.reflect.BeanProperty

class Car(@BeanProperty val year : Int, var miles : Int)

When you mark a property with the @BeanProperty annotation, the Scala compiler will create the JavaBean-style getter for that property if it is declared val and, in addition, a setter if it’s declared a var.

You can get the year using either instance.year (or instance.year() if you like, but parentheses are optional) or using the JavaBean convention instance.getYear().

Now we can focus on adding some behavior to the class. Let’s add a drive method:

import scala.reflect.BeanProperty

| class Car(@BeanProperty val year : Int, var miles : Int) {
| def drive(distance : Int) = {
| miles += distance
| }
| }

The drive method accepts a parameter, distance, and changes the miles accordingly. A good practice in Java is to declare the method parameters as final. Scala automatically treats all parameters as val (final). Any attempt to modify distance within the drive method will result in an error. Scala does not merely suggest good practices, it enforces them in quite a few places like this.

Let’s create an instance of the Car and take it for a drive.

val car = new Car(2011, 0)

| println(car.year)
| println(car.getYear())

println(car.miles)

car.drive(10)

println(car.miles)

We first create an immutable reference car that refers to a new instance of Car. We then get the value of year first using the Scala-style getter and then using the JavaBean style. Finally we print the value of miles before and after a call to the drive method. When you run the code, you will see the following output:

| > scala Car.scala
| 2011
| 2011
| 0
| 10

Since we made the miles a read-write property, we could change the miles using

car.miles = 20

If you’d rather make miles read-only from the outside, you can do that as well and provide a separate private field for access within the class. Let’s make that change and also reduce some clutter in the drive method definition.

| import scala.reflect.BeanProperty
| class Car(@BeanProperty val year : Int) {
| private var milesDriven = 0
| def miles = milesDriven
| def drive(distance : Int) = milesDriven += distance
| }
| val car = new Car(2011)
| println(car.miles)
| car.drive(10)
| println(car.miles)

Any attempt to set the values of miles, for example using car.miles = 20, will now result in a compilation error. Also, car.milesDriven = 20 is prohibited.

We saw how to create a class and instantiate an instance. In the first part of this series I mentioned that Scala is fully object-oriented. Since we’re on the topic of OO, now is a good time to revisit that.

Java has objects and primitives, and you work with them differently. In Scala you don’t have to treat them differently. For example, you can do the following on an int value:

| println(1.toString)
| println(-1.abs)
| println(1.to(3))
| println(1 to 3)

You called the toString method on an int value 1, followed by the call to the abs method, and two calls to the to method. The output from this code is:

| 1
| 1
| Range(1, 2, 3)
| Range(1, 2, 3)

As an astute reader you may have a couple of concerns at this point. First, how does it do that? Second, is there a performance consequence?

Scala has wrapper classes like RichInt, RichDouble, etc. that represent the object form of their primitive counterparts. When you perform actions like 1.to(3), Scala quietly does an implicit conversion from the value (1) to a RichInt object. RichInt has quite a few convenient methods like to, abs, etc. specific to operations on integers.

Scala converts from primitive to the rich wrappers only based on the context. If you do not invoke any methods on a primitive, Scala will simply represent that as primitive at the bytecode level. So you don’t invoke any performance degradation in those cases, the conversion applies only when it’s called for.

Being a pure OO language, Scala does not directly allow static methods. In Java you generally write both instance methods (and fields) and static methods (and fields) within a class. This lacks separation of concern and clutters the class. Also, in your mind, you have to switch context between these two when you’re implementing or modifying a class. Scala eliminates these problems by providing a clear separation.

The Scala equivalent of a Java class with only static methods is a singleton. Recollect the Singleton pattern? A pattern that takes minutes to understand and months to get right, yep, that’s the one I’m talking about. It turns out that Singleton is mired with so many problems that an entire chapter and a slew of recommendations on how to handle it is written in Effective Java by Josh Bloch. Scala is effective Java so it handles it for you, and Singleton is a first-class citizen in Scala.

You create a singleton in Scala using the object keyword as shown here:

| object Util {
| def f2c(fahrenheit : Double) = (fahrenheit - 32) * 5/9
| }

You don’t create an instance of Util, it’s the single instance. You can directly call methods on it, like so:

| println(Util.f2c(32))
| println(Util f2c 75)

On the Java side, the methods of a singleton appear as static methods, so you can invoke them as such from outside Scala.

Scala also allows a class and a singleton to share the same name. In this case, the singleton is called a companion object. A companion object and the corresponding class are quite intimate and don’t have any encapsulation boundaries between them.

Let’s use this to create a class and a factory singleton (companion) to instantiate objects.

| class Marker private (val color : String) {
| println("Creating marker of color " + color)
| }

| object Marker {
| val markers = scala.collection.mutable.Map[String, Marker]()

| def create(color : String) = {
| if(!markers.contains(color)) {
| markers(color) = new Marker(color)
| }

| markers(color)
| }
| }

The Marker class prints a message in the constructor to indicate when an instance is created. We made the constructor of the Marker private by placing that keyword between the class name and the parameter list for the constructor. As a result we can’t create an instance of Marker directly in our code, however the companion object can.

In the companion object’s create method we check to see if a marker with the requested color already exists in a hashmap. We create an instance only if it does not exist, add it to the collection, and return an instance.

The code to use the Marker and its companion is shown next:

| println(Marker.create("Red").color)
| println(Marker.create("White").color)
| println(Marker.create("Blue").color)
| println(Marker.create("Red").color)

The first three requests are for three different colors and so three new instances will get created. The last request, however, is for a color that was already instantiated and so the cached instance from the hashmap will be returned as we can see from the output:

| Creating marker of color Red
| Red
| Creating marker of color White
| White
| Creating marker of color Blue
| Blue
| Red

Scala greatly simplifies and streamlines the everyday task of OO programming by providing sensible conventions. It reduces the amount of code you have to write/maintain and brings clarity by separating instance-related members and class (static)-related members. We discussed the OO aspects of Scala in this part, and we’ll look at the functional style in the next.

Dr. Venkat Subramaniam is an award-winning author, founder of Agile Developer, Inc., and an adjunct faculty at the University of Houston.

He has trained and mentored thousands of software developers in the US, Canada, Europe, and Asia, and is a regularly-invited speaker at several international conferences. Venkat helps his clients effectively apply and succeed with agile practices on their software projects.

Venkat is the author of .NET Gotchas, the coauthor of 2007 Jolt Productivity Award winning Practices of an Agile Developer, the author of Programming Groovy: Dynamic Productivity for the Java Developer and Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine. His latest book is Programming Concurrency on the JVM: Mastering synchronization, STM, and Actors.

Send the author your feedback or discuss the article in the magazine forum.

Test-Driven Development

A Guide for Non-Programmers

by Jeff Langr

Jeff presents a clear explanation of what Test Driven Development is all about, and what its potential benefits and risks are.

Test-driven development (TDD) is a programmer practice that’s been employed by a growing number of software development teams for the past dozen years. Does TDD impact you personally? If you’re a manager, what should you expect from teams using TDD? How do you know if they’re doing a good job? Is there any advantage of TDD over sporadic after-the-fact unit testing?

First publicized widely with the advent of extreme programming in the late 1990s, TDD is a simple discipline that programmers use in their day-to-day, minute-to-minute building of software systems. The mechanism of TDD is simple:

Capture a small piece of system specification in the form of a coded software test.

After demonstrating test failure, build the smallest amount of production software that meets this specification—in other words, write the code that makes the test pass (and doesn’t break any existing tests).

Review the new code in conjunction with the existing system, correcting any deficiencies in its design or the overall system design (this step is also known as the refactoring step).

A programmer repeats these three steps continually, with each cycle incrementally introducing a small piece of new behavior into the system.

Imagine growing a system in this manner from day one. By definition, all features in the system are documented in example form. Also by definition, all features in the system have been tested in some form. What sort of benefits can accrue from this practice? What costs does it carry?

Practicing TDD requires no high-end, high-cost tools (although value-adding, more sophisticated tools do exist). The tool of choice for TDD practitioners is a simple unit-testing framework that developers can download freely for virtually all modern programming languages. From a software management perspective, continuous integration (CI) tools such as Jenkins or CruiseControl can easily incorporate unit test execution into their build cycles. The builds are configured to fail if any of the tests fail—an indication that there may be a problem with the integrated software. Programmers can also track test execution statistics using such build environments.

The tests produced by TDD are of a different nature from tests produced by a QA or testing team. First, TDD tests are almost always written in the same language as the production system. Java test drivers code their tests in the Java programming language, C# programmers code their tests in C#, and so on. Second, since the tests are written in a programming language, TDD tests are designed, implemented, and consumed only by programmers (although you might have visibility into the tests, sometimes through the CI server).

Primary Benefits of TDD

The development team seeks several benefits from employing TDD. The surface-level benefit is a higher-quality system: with every feature comprehensively unit tested, TDD can help produce software with significantly lower defects. For example, a TDD team at a large insurance company delivered a ~100,000-line Java application against which only 15 defects were reported in its first 11 months.

TDD also has the potential to provide “living documentation” (see Adzic, Gojko, Specification By Example, Manning Publications, 2011) for the classes in your systems. Programmers craft their TDD unit tests so that other developers can rapidly understand the code feature being tested. Such specifications by example stay in sync with the code, and provide a reliable way for developers to increase their understanding of system capabilities.

Design of a system is dramatically impacted by a team embracing TDD. The interest in unit testing immediately drives toward higher levels of cohesion and lower levels of coupling—the two primary indicators of a well-designed object-oriented system. This shift comes about primarily due to the simple fact that it is easier to test-drive a system with such a design.

More importantly, having the tests produced via TDD creates high levels of confidence to change the software. The significance of the ability to continually change code with low risk cannot be overstated. In an iterative/incremental development environment such as agile, you have no choice but to accept frequent changes to the code. TDD allows you to continually adapt the design to these changing needs. In other environments, the inability to safely change code leads to more rapid degradation of code quality, almost by definition.

The ability to change code safely also helps minimize the amount of unnecessary code in a system. One team was able to reduce their code base from 180,000 to 60,000 lines of code in 10 months by test-driving new features and incrementally adding tests to existing code. Casual analysis of most systems will suggest that most could be easily reduced in size by half, if only the developers had a safe means of doing so. This decrease in production code size can simplify maintenance and reduce the risk created by excessive code duplication.

Costs and Limitations of TDD

As with any new technique worth adopting, TDD incurs a learning curve overhead. You’ve already seen the three simple rules of TDD—that’s really all there is to it. But the “how to” isn’t the tough part. Instead, the primary challenge lies in developer habits: It’s difficult for programmers with significant experience to re-learn their core approach to building software (and even more difficult for some to accept that their long-ingrained approaches hold room for improvement).

Success in transitioning to TDD will thus mostly depend on the enthusiasm of your team members, their ability to work together and support each other, and their interest in continual introspection to recognize and fix approaches that need improvement. A team aligned with all of these conditions might have a solid foothold on TDD within a month or two. A group of individuals comprised of dissenters and apathetic programmers will likely not succeed without reorganization or intervention.

The actual labor cost of TDD is hard, if not impossible, to quantify. One study makes only the conclusion that quality increases but development slows with TDD. Other studies have demonstrated that initial development time increases from 15% to 35% but with increased quality.

The question becomes, what is the value of “increased quality?” Cost assessments for programming effort rarely include things like developer rework costs during the testing phase, the cost in delayed release, the cost of help desk/support time, the increased cost to introduce a new feature because the code is not clean, or the cost of losing a customer who leaves due to devastating defects.

TDD will not solve all development problems. It is only a portion of what is required to increase quality in your systems. TDD must be bolstered by additional testing, including some integration testing, acceptance testing, load/performance testing, and exploratory testing (to name a few). It still demands review of the software produced, and introduces a new need to review the tests as well. TDD is also not an end-all for design: You should still consider high-level up-front design, and you should still discuss design as a team on a frequent basis.

TDD is also not a substitute for thinking. While TDD derives code well for the vast majority of algorithms in your system, it will not necessarily help you with the insights needed for some complex algorithms (a rare need in most systems).

Metrics and Code Coverage

As a manager, how do you know anything about the quality of the unit tests produced by TDD? Metrics exist that purport to provide you with useful information, but take extreme caution in making decisions based on these numbers, or when using them as goals.

The most prevalent metric in use is something known as code coverage. For each run of tests, a code coverage tool can track which production lines of code are executed. If there are 100 lines of code in the production system, and the tests happen to execute, or exercise, 75 of those lines of code, the code coverage is 75%. Other coverage metric variants exist, including one known as branch coverage, but the general idea is the same: What percentage of the code (or code concepts) is coverered by tests?

Using TDD, the theoretical outcome should be 100% coverage: if a developer only writes production code in response to the existence of a test for that code, then all code should be covered. In practice, the coverage levels are typically in the high-90% range for various legitimate reasons (some involving the language and frameworks used, some involving the need to bypass interactions with external systems).

If TDD is capable of producing such high levels of coverage, then why not institute gating criteria that says that the developers are not done unless their coverage hits the high 90s? For starters, it’s possible to attain high coverage metrics while producing poor tests that provide little value. The coverage number simply indicates whether or not code was executed, not whether it was proven to actually work. Trusting a coverage number is akin to trusting a programmer who says, “It compiled on my machine, let’s ship it!”

Most programmers aren’t nefarious, but in environments where they are expected to meet metric goals, many learn to make the least possible effort in order to meet the goal. In the worst cases, the quality of the tests is totally ignored. Over time, these tests become far more costly to maintain, which may ultimately lead to their abandonment.

Technical metrics such as coverage are best consumed by the technical team only. Developers can learn how to improve their approach to TDD by exploring the areas in the code that are not properly covered. Low coverage numbers act as beacons for the team to uncover and correct trouble spots (not just in the code but in adherence to the practice).

So how do you know if the programmers are doing TDD well? Ultimately, the only metrics that matter and can’t easily be “gamed” are customer or business facing metrics: customer satisfaction, number of defects, rate of delivery, and cost of development. The application of TDD should be able to impact these numbers (although other factors may negate these gains).

If your team has employed TDD for a while, and you haven’t seen any customer-facing numbers improve, either your team is struggling with TDD, or other factors are in play. One possiiblity is that the programmers are challenged by a significant amount of existing code that remains untested. Too often, these legacy codebases are overly complex, and any changes can quickly generate numerous defects.

Beyond the customer-facing numbers, the tests themselves and design of the production system should be of high quality. Some facets of quality can be gleaned from metrics such as code complexity and code coupling, but the only way to truly know is to examine the test code and system design. That effort of course requires someone who knows what good tests, code, and design look like (and who is also someone you can trust).

TDD vs TAD

Many developers write unit tests after the fact—for code they’ve already built. A common term for this practice is POUT: Plain Old Unit Testing. I’ve also introduced the term Test-After Development, (“TAD”) as a more direct contrast to TDD.

It’s theoretically possible for a TAD developer to produce tests and code of quality and comprehensiveness comparable to TDD. In reality, it doesn’t happen, for several reasons.

Developers writing unit tests after they’ve built the code typically have already tested the code manually. Developers view these tests as a double-check at best; more cynically, they view the tests only as fulfilling the wishes of some team or management mandate. They write no more tests than required: “I’ve already proven my code works, why do I need to write tests for it?” For similar and other reasons, TAD tests are typically written only for a happy case and perhaps a small number of edge or exceptional cases.

Time is always a factor in software development—delivery always takes precedence over anything that happens between the code being written and being shipped. Testing gets short shrift, and even more so any development practice that falls in this time span, including reviews and TAD. In other words, these activities are a tad too late.

TAD programmers rarely go back and change the design of the system once unit tests are in place. Running out of time is again one reason, another is the lack of any immediate rationale to do so. So unlike TDD, where keeping the code base clean through refactoring is a built-in step, entropy will rapidly take over in a TAD system.

TAD proponents claim a typical coverage level of around 70% and believe that this is good enough. However, that means at least a quarter of your system remains rigid, and cannot be as safely or rapidly changed as business needs change. Some of the most complex and risky logic in your system will lie in that 30% of code without unit tests. Even if you have an excellent suite of acceptance tests to catch problems, changes in this area will come more slowly over time.

Recommendations

TDD is a skill that takes effort and desire to learn. Your team must agree that it is an appropriate tool for their circumstance. You should also seek to seed your team with at least one person with appropriate experience. TDD does not come without cost, but the potential benefits of test-driven development are too significant to dismiss.

Jeff Langr is a veteran software developer with almost 30 years of professional software development experience. He is the author of three books: Agile in a Flash (written with Tim Ottinger and published in February 2011 by The Pragmatic Bookshelf), Agile Java, and Essential Java Style, as well as over 100 articles on software development (see http://langrsoft.com). Jeff owns the software consulting and training consultancy, Langr Software Solutions.

Send the author your feedback or discuss the article in the magazine forum.

Self-Inflicted Scope Creep

When Stories Grow Out of Control

by Jonathan Rasmusson

Sometimes our biggest problems are of our own making.

Self-inflicted scope creep happens when a team increases the scope of their project without their customers actually asking for anything new. It’s painful to watch because it can mess up your plan, create fear and anxiety, and undermine the trust you’ve worked hard to gain with your client.

In this article I’ll show what self-inflicted scope creep looks like, and what you can do to stop it from happening on your project.

The Incomplete Story

When a team takes a story to work on during an iteration, the intent is that they’ll finish it. That’s why we like our stories to be small (something that can be done in a couple of days).

Sometimes, however, a story is bigger or more complex than we think. And despite our best efforts, we aren’t able to finish it during an iteration.

Not finishing a story once in a while isn’t a big deal. It happens. Where things can go awry is how we handle it.

One team I coached (that was of course under a lot of pressure) got into the habit of taking unfinished stories and splitting them into new stories at the end of an iteration.

They would break the old story (5 points) and break it into two parts. One part they would claim as done (say 3 points). The other part they would say was not done (say 4 points).

So now they have two stories (7 points) instead of one (5 points).

On its own, this isn’t that big a deal. What’s 2 points?

But if you keep doing this long enough something strange starts to happen. The team noticed that their burn down chart started to look something like this:

This is what I call self-inflicted scope creep. It’s not real scope creep, as there is no new work. But it’s malicious because it creates confusion in planning and leads to uncomfortable conversations with your client.

Agile planning works when stories are sized relative to one another. The fact that as humans we are pretty good at sizing things relative to each other is powerful. So long as we size things relatively and track how fast we are going, we’re in good shape.

But if we keep taking stories and slowly increasing their individual sizes over time it messes things up. When our stories stop being sized relative to one another we lose the ability to predict when we are going to be done.

Let’s now take a look at how we should handle unfinished stories, and how to treat new ones we discover along the way.

Don’t Count It Till It’s Done

New stories are easy. If you discover a new story, simply write it down and move on. Esimate it and prioritize it like the others but don’t sweat it. We knew we’d discover new stories along the way so it’s no big deal.

Unfinished stories, however, are different.

The first rule of thumb is to simply carry the unfinished story over. Agile is pretty binary about stories being done—either it’s done or it’s not. There is no 90% done.

So it’s usually simplest to just leave the estimate the same and carry it over to the next iteration (and for every story that’s a few points over there are always a few under so it all comes out in the wash).

If your story is a lot bigger than you originally thought, just re-size it relative to the others.

If your story truly is epic, you can also split it. But this should be the exception rather than the rule. We are trying to get working software out the door after all, and if you find yourself continuously splitting stories, they may be a little bit big to begin with.

But usually the best thing you can do is simply carry it over. It keeps things simple, accurately reflects how long things are taking, and it’s telling you something. If it’s taking this long to do this story it’s probably going to take that long to do others similarly sized—which is what we want.

The Flip Side

Now not all scope creep is bad. In fact it can be very good—nowhere more so than if you are in a startup.

Sometimes you build the wrong thing. It’s not what your customer wants and to continue down the original path you set out is crazy. The startup community recently started calling this a “pivot,” and it happens all the time. (Did you know Flickr started out as an online game? People didn’t really like the game but they discovered that their players sure liked sharing photos.)

This doesn’t happen as much with corporate project work but it still happens. Your customers are going to change their minds, and you are going to have ideas for how they could improve their product. It’s your duty to share that with them (new scope be damned) and quite frankly most enterprises could use a dose of startup, so do share your new ideas.

So as my friend Andy Hunt says, context matters, and yes some self-inflicted scope creep can be good. But the kind I am focusing on here is related to messing up your planning and estimates, and a simple reminder for how to handled unfinished stories at the end of an iteration (don’t count them).

Keep It Simple

Agile planning isn’t rocket science. At the end of the day how you manage expectations on your project is totally up to you. Everyone has their own style, and it’s more art than science. So if you feel compelled to create a new story to manage expectations in a certain way, it’s not a big deal.

The point of this article was just to make you aware of a trap that new teams (and old) sometimes fall into.

If you are new to agile, my advice is to start simple and do it by the book—simply carry unfinished stories over to the next iteration and call them done when they’re done.

If you’ve been doing agile for a while, have built some rapport with your customer, and have earned their trust, you’ll have a lot more leeway in how you track and report progress. Eventually, you won’t need estimates at all and they will just trust you to get the work done.

Jonathan Rasmusson is the author of The Agile Samurai. As an experienced entrepreneur and former agile coach for ThoughtWorks, Jonathan has consulted internationally, helping others find better ways to work and play together. When not coaching his sons’ hockey teams or cycling to work in the throes of a Canadian winter, Jonathan can be found sharing his experiences with agile delivery methods at his blog, The Agile Warrior. For more information on the Agile Inception Deck check out The Agile Samurai.

Send the author your feedback or discuss the article in the magazine forum.

Root Cause Analysis from Long Ago

Have We Learned Anything in 23 Years?

by Brian Tarbox

Cleaning out his basement, Brian comes across a document that shows how little programming has changed in 23 years.

A few weeks ago I was cleaning out my basement, and while going through old papers I came across the following:

It was a hand-written root cause analysis data sheet from a project I had worked on back in 1988! It was amusing and a bit satisfying to know that I had been thinking about root cause analysis over 23 years ago, long before things like TDD, BDD, Agile, Scrum, Java, or Linux even existed. On the other hand, it was a bit depressing to realize that in many ways the field has not made much progress in the intervening two decades.

This project was for one of my first consulting jobs and the assignment was to develop either a basic checkwriting program or a full Accounts Payable and Billable system. If you’re puzzled by that “or,” so was I. The manager told me that they were not sure which product they were going to build but that I should start coding right away because I was an expensive hourly contractor, and that they’d decide which product I was building in a month or two.

I wish I could say I was making that up, but it’s true. Faced with that problem I decided to spend the limbo months developing utility classes that would be needed for either project.

Given this background it’s not surprising that the highest percent cause of the bugs came from incomplete requirements. That certainly hasn’t changed. It’s also interesting that the most reported category ended up being “not a bug.” That speaks to a low level of communications between development and testing (there was no notion of QA being a key part of the development team back then).

If we convert the categories from 1988 style to current terms and combine them a bit we get:

And if we then graph those categories we get:

That pie chart looks like it could have come from one of my current projects! With all of our progress, with our Integrated Development Environments, our Test Driven Development, Agile Methodologies, and such, we haven’t made a lot of progress of reducing the bugs or even changing where they tend to come from.

I wonder how much of my cumulative salary over the past 23 years has been spent working on what turned out to be late, incomplete, or flawed requirements? What is the cumulative delay in all the projects I’ve worked on due to such things? I still hear people say “we don’t have time” and “quality is too expensive.” I guess I’m preaching to the choir because if you’re reading this magazine it’s safe to assume that you get it, but clearly we haven’t sold our message to the mainstream—and I wonder why.

I have to believe that a lot of the problem comes from how we train developers. I’ve said it before but most software students have never seen a requirements document. And if you count a class assignment as a requirement they’ve certainly never seen feature creep or shifting requirements. How can they deal with something they’ve never trained for?

What Actually Got Built?

By the way, the project ended up creating a form-filling program that supported a family of small business forms such as invoices, change orders, customer statements, and checks. In all, we supported over 30 distinct form types, each with their own business rules and layouts. We also supported a wide variety of printers back in the day before generic printer drivers (which is where the “strange hardware” bug category came from).

By the way, in yet another past-is-prologue moment we were hit with a patent infringement claim from a disgruntled ex-employee the week before we were going to ship. Back in the day of continuous-form printing it was crucial to get the top of the form aligned with the top of the printer. The forms had numbers along the side and the program would print an “X” in the margin. The number where the “X” was printed told you how many lines to manually move the paper in the printer. The folks at the USPTO gave this ex-employee a patent on the formula “Lines Per Form - X_Location = LinesToScroll”!

In the week before our major product rollout we changed the alignment method to “print the alignment character and then adjust the paper. Repeat until the “X” is printed at line 1.” That apparently passed muster as being different enough to be non-infringing. Given the current Apple/Google/everyone patent wars, it doesn’t seem like much has changed!

Brian Tarbox is a Distinguished Member of Technical Staff at Motorola where he designs server-side solutions in the Video On Demand space. He writes a blog on the intersection of software design, cognition, and Tai Chi at briantarbox.blogspot.com. His primary contact point is about.me/BrianTarbox.

Send the author your feedback or discuss the article in the magazine forum.

When Did That Happen?

The Computer Virus

by Dan Wohlbruck

One person predicted the coming of computer viruses. He also invented them.

On November 3, 1983, a graduate student named Fred Cohen was sitting in a computer security course at USC taught by Turing-award winning Professor Len Adelman. Daydreaming, Cohen conceived of a trojan horse that would be inserted into a host computer and then replicate into the other programs that resided there. A week later, on November 10, 1983, he demonstrated the first piece of malware to be called a computer virus.

In his paper “Computer Viruses—Theory and Experiments,” published in 1984, Cohen defined a computer virus as “a program that can ‘infect’ other programs by modifying them to include a possibly evolved copy of itself.”

Cohen concluded that computer viruses posed a severe threat. A computer infected with a virus was bad enough, but what if computer viruses could spread from computer to computer, like viruses spread from person to person. Indeed, Cohen warned that “[i]t appears that they can spread through computer networks in the same way as they spread through computers, and thus present a widespread and fairly immediate threat to many current systems.”

In 1986, Cohen completed his PHD dissertation at Lehigh University and was told that a computer virus could never work in a real computer system.

The Generation of Viruses

As events unfolded, later in 1986 the BRAIN virus began to infect IBM PCs. Written by two brothers in Pakistan, Amjad and Basit Alvi, the code was intended to stop the piracy of their medical diagnostic software. Amjad Alvi described BRAIN’s activities as checking the significant bit of the MS-DOS BIOS and if it was clear, BRAIN didn’t infect the disk. The sole purpose for BRAIN, he insisted, was to track and stop illegal copies of the disk.

In 1987, computer viruses became epidemic. The Jerusalem virus, the Byte Bandit, and the Christmas Tree virus, among others, were all released in 1988 and each created its own brand of havoc. Networks were overloaded or disrupted and individual PC files were corrupted or destroyed.

An IBM research paper reports that by August 1989, there were about 30 detected computer viruses. The paper then describes the events of December 1989:

“The Dark Avenger.1800 virus was reportedly written in Sophia, Bulgaria by an individual calling himself Dark Avenger. It well represented the coming escalation in the virus vs. anti-virus war. This virus introduced two worrisome features. First, it was designed to do slow, insidious damage to the system rather than sudden, obvious damage. It would randomly write garbage to sectors of the drive. So damage would tend to go unnoticed. In turn, damaged files would be backed up. Second, it was a fast-infector. Resident viruses before this would infect programs as they were run. Dark Avenger also infected programs if they were opened. Therefore, if the virus was in memory and you ran an anti-virus scanner (that wasn’t aware of the virus) on the system, the virus would piggyback on the scanner and infect every program the scanner looked at.”

Throughout the 1990’s Dark Avenger led to the Michelangelo Virus, a variety of macro viruses, Melissa, and then the Love Bug viruses. Each virus was met, neutralized—and quickly replaced by another.

Today, it’s estimated that over 10 percent of the world’s PCs are infected with malware of one type or another.

A Prophet without Honor

As for Fred Cohen, by 1992, he became disillusioned. He recounts that despite his attempts to call attention to the potential for the spread of the computer virus by way of networks and in response to his requests for grants and research assistance, he never received so much as a dollar in aid nor even an encouraging word from any governmental source. He insists that he was blackballed.

Cohen believes that there are three alternative futures with regard to computer viruses. Either things will just keep going as they are, or viruses will take over everything, or viruses will become extinct. The man who coined the term believes that the threats are evolving and the our defenses had better evolve, too.

It began 28 years ago—and that’s when it happened.

A Reader Writes

Bob Wonderly comments on last month’s history article:

But the mechanical comptometers were implemented differently than the mechanical adding machines in a couple important ways (other than not printing): they did the addition and the carries as soon as a key was pressed, there was no need to pull a lever as was the case with adding machines. And they did subtraction by a nines-complement and add approach so each key had two numbers imprinted on it, a big number for the more common add and a little number for the nines complement.

In the adding machines (remember I am talking about the mechanical ones) the digits were all set up and the addition with all the necessary carries took place when the lever was pulled.

You’re right that the adding machine became more popular but a skilled operator could go faster with a comptometer.

The early Remington Rand Univac (a precursor to Sperry) Scientific digital computers (1101, 1102, 1103—the commercial version) had a subtracting accumulator and did additions by complement and subtract. I presume the point was to make the logical circuitry for the accumulator simpler since it was implemented with vacuum tubes.

Enjoyed your article. I grew up around mechanical office machines since my father’s career was repairing them. My first programming job was programming the 1103 in the summer of 1955. At first we coded the raw octal number commands—both ops codes and address (operand addresses and instruction addresses). But it wasn't long before someone figured out that that approach was too intense, especially when bug fixing required inserting instructions between other instructions and thereby totally messing up your carefully worked out instruction addresses. Thus the beginning of a precursor to assembly language.

Dan Wohlbruck has over 30 years of experience with computers, with over 25 years of business and project management experience in the life and health insurance industry. He has written articles for a variety of trade magazines and websites. He is currently hard at work on a book on the history of data processing.

Like this article? Hate it? Send the author your feedback or discuss the article in the magazine forum.

Calendar

Author sightings, partner events, and other notable happenings.

We often want to call your attention to a particular event, and this month a couple have caught our eye.

Nov 10–12, clojure-conj, Raleigh, NC

clojure-conj

Stuart Halloway and Aaron Bedra, co-authors of Programming Clojure, 2nd Edition (among others)

Dec 3, ErlangDC, Dulles, VA

An Epic One-Day Erlang Conference in Washington, DC

organized by the local DC Erlang Meetup Group

Author Appearances

Who’s where, and what for.

Oct 30–Nov 4, AYE Conference, Cary, NC

“Project Bloat Doesn't Float,” “Replacing Management Myths with Effective Practices,” “Influence and Authority: Using Your Personal Power to Get Things Done,” “Adapting to Change in Your Life,” and a one-day workshop: “Making Geographically Distributed Projects Work”

Johanna Rothman, author of Manage Your Project Portfolio: Increase Your Capacity and Finish More Projects, Manage It!: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors: Secrets of Great Management

Nov 3, Java2Days, Sofia, Bulgaria

“Regex—The future programmer’s best friend”

Staffan Nöteberg, author of Pomodoro Technique Illustrated

Nov 4, Java2Days, Sofia, Bulgaria

“Pomodoro Technique”

Staffan Nöteberg, author of Pomodoro Technique Illustrated

Nov 5, Ruby Midwest, Kansas City, MO

“Make Awesome Command-Line Apps with Ruby”

David Copeland, author of Build Awesome Command-Line Apps with Ruby

Nov 5, Midwest Ruby Conf, Kansas City, MO

Modern Databases

Eric Redmond, co-author of Seven Databases in Seven Weeks

Nov 5, Midwest Ruby Conf, Kansas City, MO

Keynote

Andy Hunt, Pragmatic Programmer

Nov 6–11, Better Software Conference East, Orlando, FL

Three tutorials: “Tuning and Improving Your Agility,” “Agile Project Design: Building Strong Backlogs,” “Agile Estimation and Planning: Scrum, Kanban, and Beyond”

David Hussman, author of Cutting an Agile Groove

Nov 7–9, Clojure/conj, Raleigh, NC

“(with-training Clojure/conj)”

Aaron Bedra, co-author of Programming Clojure, 2nd Edition

Nov 12, Chippewa Valley Code Camp 4, Eau Claire, WI

“Web Development With CoffeeScript and Sass”

Brian Hogan, co-author of Web Development Recipes

Nov 12–13, Voices That Matter: iOS Developers Conference, Boston, MA

“Core Audio Cranks It Up” and “Capturing Stills, Sounds, and Scenes with AV Foundation”

Chris Adamson, co-author of iPhone SDK Development

Nov 16, QConSF, San Francisco, CA

“One () to rule them all”

Aaron Bedra, co-author of Programming Clojure, 2nd Edition

Nov 16, Agilis, Reykjavik, Iceland

Workshop

Rachel Davies, author of Agile Coaching

Nov 18, SCNA, Chicago, IL

“Simplicity”

Aaron Bedra, co-author of Programming Clojure, 2nd Edition

Nov 18–19, Software Craftsmanship, North America, Chicago, IL

“Practice techniques in other disciplines”

David Chelimsky, co-author of The RSpec Book

Nov 22, Best of DevSum, Stockholm, Sweden

“Regex in .NET”

Staffan Nöteberg, author of Pomodoro Technique Illustrated

Nov 29–Dec 2, Pragmatic Studios, Reston, VA

iPhone/iPad Programming

Daniel H Steinberg, co-author of iPad Programming: A Quick-Start Guide for iPhone Developers and author of Cocoa Programming: A Quick-Start Guide for Developers

Dec 2, Cocoaconf, Raleigh, NC

Keynote

Andy Hunt, Pragmatic Programmer

Dec 2–3, Cocoaconf, Raleigh, NC

“Core Audio Cranks It Up” and “Capturing Stills, Sounds, and Scenes with AV Foundation”

Chris Adamson, co-author of iPhone SDK Development

Dec 3–4, CocoaConf, Raleigh, NC

Keynote: “Objective-C: the Director’s Cut”

Daniel H Steinberg, co-author of iPad Programming: A Quick-Start Guide for iPhone Developers and author of Cocoa Programming: A Quick-Start Guide for Developers

Jan 11-13, CodeMash, Sandusky, OH

“Developing With iOS 5 ” and “iOS Networking: Bonjour, iCloud!”

Chris Adamson, co-author of iPhone SDK Development

Jan 11–13, CodeMash, Sandusky, OH

“Mac Development for the iOS Developer” and “Storyboards: New development in iOS5”

Daniel H Steinberg, co-author of iPad Programming: A Quick-Start Guide for iPhone Developers and author of Cocoa Programming: A Quick-Start Guide for Developers

Jan 23–27, OOP 2012, Munich, Germany

Tutorial: “Influence and Authority: Using Your Personal Power to Get Things Done,” Talk: “Six Behaviors to Consider When Hiring for an Agile Team”

Johanna Rothman, author of Manage Your Project Portfolio: Increase Your Capacity and Finish More Projects, Manage It!: Your Guide to Modern, Pragmatic Project Management, and Behind Closed Doors: Secrets of Great Management

O’Reilly Events

Upcoming events from our friends at O’Reilly.

Nov 8–9, Velocity Europe, Berlin, Germany

Velocity Europe: “Velocity Europe is the convergence of performance and site reliability experts and rock stars who share the unique experience that can only be gained by operating at scale. At Velocity, leading experts share their knowledge about how you can make your site scalable, reliable, and fast.”

Dec 6–7, Velocity China, Beijing, China

Velocity China: “Network performance, operation, and maintenance, once the secret weapon of the elite of the Internet companies, is now an important part of the online strategy of all Internet companies.”

USENIX Events

What’s coming from our USENIX friends.

Dec 4–5, CHIMIT 2011, Boston, MA

ACM Symposium on Computer Human Interaction for Management of Information Technology: “At CHIMIT, researchers and practitioners share issues, solutions, and research drawing upon fields such as human-computer interaction, human factors, computer systems, and management and service sciences to address cognitive, social, and technical issues in managing the increasing complexity of modern IT systems.”

Dec 4–9, LISA '11, Boston, MA

25th Large Installation System Administration Conference: “LISA ’11 will break out the time machine and take you on a journey of system administration through the years via top-notch training, innovative research, Practice and Experience Reports, and that all-important face time with others confronting the same challenges you battle everyday.”

Dec 12–16, Middleware 2011, Lisbon, Portugal

ACM/IFIP/USENIX 12th International Middleware Conference: “The scope of the conference is the design, implementation, deployment, and evaluation of distributed system platforms and architectures for future computing and communication environments.”

Shady Illuminations

You Have to Be Light on Your Feet to Play in the Clouds

by John Shade

John has seen the future, and it’s a roach motel.

It is no wonder, that about the remote Borders of it there are produced both Men and Beasts of monstrous Shapes, considering the Agility of the Fiery Heat to frame Bodies and carve them into strange Shapes. -Pliny the Elder

Mark Benioff says Oracle is building the wrong software for the cloud era.

Well, the CEO of Salesforce.com would say something like that, wouldn’t he? A former Oracle executive, now in fierce competition with his former boss. Then, too, it’s always fun to battle with Larry.

“Being made fun of by Larry Ellison... is, for me, the highest honor there is,” tweets James Lindenbaum of Heroku.

Still, maybe Benioff has a point. Oracle does seem to be lacking a certain agility. A 21st Century corporation has to be light on its feet.

I’m too Agile for My Shirt

I’m sure you’re asking yourself, “What major companies does John think are among the light-footed? Who does he see making agile moves that you wouldn’t expect from a large company?” Well, I can think of a few companies that are pretty agitated.

There’s Netflix. They start charging for something they had been offering for free and the world and its dog naturally sees this as a huge price increase. They spin off the original core of their business using a name that has porn connotations and are forced to recant on that within days. The CEO finds himself posting more or less daily to his apology blog. Well, backpedaling frantically on unpopular changes is one kind of agility. Netflix is darting here and there and back again, moving like a border collie, shedding customers like an akita. And this quick-footedness is effective—in that it is having the effect of driving customers to competitor Redbox.

In related news from the Bizarro world, Redbox just raised it prices and is still gaining customers. Because agility has nothing to do with consistency.

HP is also showing some impressive agility for an old, tired horse.

“We’re buying WebOS. We’re selling WebOS. We’re shutting down the PC division. We’re keeping the PC division.” Now that’s flexibility.

I’m still not clear on WebOS. Is it on the way out? But if you know, don’t tell me, tell Meg Whitman. She’d really appreciate a clue as to what the company’s doing.

How agile is HP? HP is so agile that developers are bailing out to go to Nokia. Does Nokia even develop software? Didn’t they outsource that to Microsoft?

Nokia is a company whose latest moves display all the style and coherence of a captcha text. I’ve given up on trying to track those crazy Finns. They’re now the 27th most respected brand—in Finland. Nokia’s doing its agile best to wiggle right out of its corporate shirt.

Their shirt-losing gyrations are nicely in sync with the smart phone service provider market, which is moving with such agility that iPhone contracts have already worked down the food chain to a couple of guys in Mississippi with two tin cans and a string.

And then, off on a cloud of its own puffery, is Google. Surely Google is the axis of agile. They invented the concept Never Out Of Beta, and made being a Labs guinea pig trendy. They redefine evil as good: peer-to-peer, which we’ve been taught is evil, is good if Google’s doing it, because Google can do no evil.

Google reinvents its product mix so much that columnists get paid to explain how to move your stuff from one Google social media platform to another Google social media platform.

Unnoticed is the fact that Google has agiled itself out of being the go-to tool for search—at least if the search is for current news. When you were trying to get up to speed on the Gaddafi story, you turned to Twitter, you didn’t go to Google, right? I did get this from Google: Gaddafi became a statistic on World Statistics Day. But that’s kind of tasteless, I imagine a person with taste would say. Of course if you don’t know how to spell Gaddafi, and who does, you might have been better served by Siri.

So I think I know what Benioff means about Oracle. They’re still stuck in a product mindset. It’s oldschool to create a product, watch demand ramp up to some plateau, then know that all you can do is rev the product to keep it barely alive or start the process over with a new product, hunting for new customers. Every new product is DOA, a zombie at birth. Like all of us. As Dylan said, “he not busy being born is busy dying.”

I Have Seen the Future, and It’s a Roach Motel

But while products are born to die, markets can live forever. Customers are easier to keep than to get, and the surest way to keep them is to lock the doors once they’re inside. So the preferable business model is a roach motel. Or, to put it more attractively, Hotel California. Either way, they can check in but they can’t check out.

You start with planned obsolescence: design in the need to upgrade or replace. That’s worked pretty well for Apple. But that still gives the customers a chance to leave.

The next level of Hotel Californication is that you get those customers to become subscribers. That’s the secret to SaaS (I’d say to Salesforce.com, but I don’t want Benioff on my case): opt-out markets. They pay you by default; if they want to quit, eh, you’ll talk about it.

The ultimate goal is to get them hooked for life and turn them into a revenue stream. That’s nirvana, where the revenue cycles turn into a continuum, a flow. And then it’s really you as much as the customer who is hooked, living in the junkie’s dream of a permanent connection, a steady drip of the good stuff.

There’s your 21st Century business model. Mutual addiction.

John Shade was born under a cloud in Montreux, Switzerland, in 1962. Subsequent internment in a series of obscure institutions of ostensibly higher learning did nothing to brighten his outlook. This column was made on equipment shared with milk, peanuts, tree nuts, and a cat. Send the author your feedback or discuss the article in the magazine forum.

But Wait, There’s More...

Coming Attractions

This may be the last page, but that doesn’t mean it’s the end of the conversation. Keep up with what’s going on in the Pragmatic universe by subscribing to our newsletter and drop by the Pub again next month for more Pragmatism. We’ll keep a seat warm and a mug chilled and a candle burning in the window.

Coming Soon in PragPub

David Bowman and David Hussman have works in the queue. Plus, as it’s our 30th issue, we may do something retrospective-ish.

Coming Soon on the Bookshelf

The Developer’s Code, Programming Node.js, New Programmer’s Survival Manual, Seven Databases in Seven Weeks, and a few surprises.

Right. But to really be in the know, you need to subscribe to our weekly newsletter. It’ll keep you in the loop, it’s a fun read, and it’s free. All you need to do is create an account on pragprog.com (email address and password is all it takes) and select the checkbox to receive newsletters.

While you’re waiting for the next issue of the newsletter or of PragPub to come out, you can follow us on twitter at @pragpub, @PragmaticAndy, or @pragdave. Or on Facebook at facebook.com/PragmaticBookshelf. Or email us at michael@pragprog.com.