Showing posts with label o'reilly. Show all posts
Showing posts with label o'reilly. Show all posts

Thursday, March 18, 2010

97 Things Every Programmer Should Know



Another useful book in the "97 Things" series from O'Reilly has been published, this time for programmers. My contribution is "How To Use A Bug Tracker". There are more details at O'Reilly and Amazon.

This book was created by each person adding their contributions to a Wiki, where it was edited and discussed. The whole process worked really well due to the editor, Kevlin Henney.

p.s. My photo on the cover is four rows down, third from the left, just in case you're looking.

Tuesday, November 13, 2007

Choosing Project Names


The discussion What' in a Project Name? over at Coding Horror reminded me of section 3.6.1 of my book Practical Development Environments:

Project names are usually chosen by engineering groups, with one name for each significantly different version of the products that they are working on. There should be no need to change a project's name once it has been chosen. Product names, on the other hand, are the names that customers see, and these names are usually chosen to help a product sell or to become popular. Product names can change at the whim of a market research poll or a new VP of Sales.

Some general guidelines for choosing names for projects are:

Keep it short

Since project names may appear in filenames or source code, shorter project names are preferable; four to six characters is common. Longer names will only be abbreviated anyway, and usually in two different ways.

Use distinctive sounds

Project names should sound different from each other when spoken aloud by people whose native language is not the one used by the rest of the group. Even if everyone speaks English, having two projects named "ctest" and "seebest" is too close for comfort.

Use low-frequency letters

It's much easier to be confident that all references to a project name can be found if the name contains characters that are less common in the local language. This is a good argument for choosing project names that use unusual characters, such as the letters q and z for English.

Apocryphal aside: a few years ago there was a project named IDS that apparently had a function named IDSConnect. Then the project was renamed DIS and all its functions were renamed accordingly, which led to their function for creating connections being renamed to DISConnect. The letters d, i, and s are too common in English to simply reuse them in
such an anagram.

Make it unmarketable

Sometimes a project name will be reused as a product name, but not if it is already trademarked, or if you make it odd or crude enough! Project names don't have to have a theme, though that can be fun. They don't even have to be meaningful, just memorable with an obvious way of pronouncing the word. You can choose a number of suitable names once and then let people decide which one they want to use next. Names of stars, types of sushi, rare diseases, and characters from comic books are some ideas to start with for project names.

Wednesday, July 18, 2007

The Lack of Difference between Priority, Severity, and Urgency

Chapter 7 of Practical Development Environment discusses tracking bugs. This article expands on ideas about bug priorities from there. The short version is "life is simpler if you rename all your priority fields to show who cares about one."

The strip is from Hans Bjordahl's very funny Bug Bash site.

Priority, Severity, Urgency, ... huh?

Most bugs have a field to indicate how serious the bug is. A common series of values goes something like this:
  • 1 - The bug stops the product, and no workaround is possible
  • 2 - The bug stops the product, but a workaround is possible
  • 3 - The bug breaks a minor part of the product
  • 4 - The bug is cosmetic or an irritation
To make this field useful, you have to make it really easy for users to find out what each value is supposed to mean, right when they are entering the bug. Some people expect higher values to mean that the bug is more important. Some bug trackers provide tiny little icons to confuse you still further because you can't remember what each icon means.

Where's that Thesaurus?

But there are more serious problems with this field in practice. The first problem is that English has a lot of words for some rather similar ideas. Quick, does "priority" mean the same as "importance"? What's the difference between "urgency" and "severity"? If English is not a user's first language, this makes using your bug tracker much harder work. Yes, the words do have specific meanings but if you have to stop and think about those meanings, then they're not good words to use. My suggestion is to pick one word and use it exclusively. I'm going to use "Priority" for the rest of this discussion, but you can choose your own favorite.

Priority for Who?

"But that's not right!"you mutter, "priority doesn't mean the same as urgency." Well, actually, I think it does, depending on who's priority we're referring to. For instance, the priority of a particular bug for the engineering team is a totally different thing from the priority of the very same bug for a Sales Engineer on site with a customer breathing down their neck. The different words usually mean priority for different groups of people. If they really do mean different things, then make it more obvious. For instance, use "Due Date" instead of "Urgency" to make the sense of time explicit.

My key suggestion is to have multiple priorities for a bug but name them per team. For example, the fields could be Development Priority, QA Priority, Support Priority, and so on. You can even have a "CFO Priority" for bugs that are stopping a contract being signed at the end of a quarter. That way, everyone gets to record which bugs really matter to them, and then they can work out which ones get worked on first. And as a side benefit, no-one gets offended when their favorite bug's priority is reduced to "Minor".

Of course, this approach means that the leaders of the teams involved in producing the product have to talk to each other regularly about what they actually want the teams to work on. Call me crazy, but that seems like a good idea to me.

Priorities that are set by Customers


One last thought: some companies allow customers to enter a priority when filing a bug. This usually becomes a "how irritated are you right now?" field. Which is useful data, but perhaps not what you originally expected to record in that field. However, when you change the value of the customer's Prioritity field, it's always a problem. If you increase the severity, the customer worries whether the problem is perhaps part of a bigger issue. If you decrease the severity, you appear to be minimizing his distress. If you provide this kind of field for customers, I suggest you allow them change the values themselves.

Wednesday, July 11, 2007

Review: Beautiful Code


Rating:

10/10
for all developers beyond their first project.
9/10 for beginners who may not see as much of the beauty yet.

Edited by longtime O'Reilly editor Andy Oram and pragmatic academic Greg Wilson, their new book Beautiful Code (O'Reilly, June 2007, 618 pages, US $44.99) is a collection of 33 chapters written by a number of people who have all written lots of ugly code, and then written some very beautiful code. Each chapter is a chance for them to describe the ideas and code that they feel stand out in a humdrum world of temporary workarounds that last forever.

The list of authors is impressive, including "K&R" Kernighan, "Pearls" Bentley, and many of the names behind some substantial modern software projects, but the first thing that I noticed about this book was lots of code snippets, in languages that range from Fortran to Python. And the code snippets are indeed beautifully formatted (with a good lay-flat binding). But in the end the beautiful code is included to make the ideas behind it all the more concrete, in which it surely succeeds.

The range of topics is the next obvious aspect, from writing a regex matcher, to what makes an API useful. I've included the whole list at the end of this review and you'll likely see something that catches your own interest.

Another theme of the book is that almost no-one gets it right first time, but just look at what can be done when you keep trying. As we hear in preschool, "the process is as important as the product", and watching any expert at work is always educational. This book describes experts' mistakes, their wrong paths, "aha!" moments and then their final successes with admirable honesty.

So how much of a developer do you have to be to appreciate this book? My guess is that you should have written a good-sized project, and then admitted to yourself that your creation was ugly. Only then can you see beauty by comparison. This book is destined to become a classic.

~Matt

Disclaimer: Greg Wilson reviewed my book Practical Development Environments in 2005, and O'Reilly sent me a copy of Beautiful Code for this review.



The book includes:

Chapter 1, A Regular Expression Matcher, by Brian Kernighan, shows how deep insight into a language and a problem can lead to a concise and elegant solution.

Chapter 2, Subversion's Delta Editor: Interface as Ontology, by Karl Fogel, starts with a well-chosen abstraction and demonstrates its unifying effects on the system's further development.

Chapter 3, The Most Beautiful Code I Never Wrote, by Jon Bentley, suggests how to measure a procedure without actually executing it.

Chapter 4, Finding Things, by Tim Bray, draws together many strands in Computer Science in an exploration of a problem that is fundamental to many computing tasks.

Chapter 5, Correct, Beautiful, Fast (In That Order): Lessons From Designing XML Verifiers, by Elliotte Rusty Harold, reconciles the often conflicting goals of thoroughness and good performance.

Chapter 6, Framework for Integrated Test: Beauty through Fragility, by Michael Feathers, presents an example that breaks the rules and achieves its own elegant solution.

Chapter 7, Beautiful Tests, by Alberto Savoia, shows how a broad, creative approach to testing can not only eliminate bugs but turn you into a better programmer.

Chapter 8, On-the-Fly Code Generation for Image Processing, by Charles Petzold, drops down a level to improve performance while maintaining portability.

Chapter 9, Top-Down Operator Precedence, by Douglas Crockford, revives an almost forgotten parsing technique and shows its new relevance to the popular JavaScript language.

Chapter 10, The Quest for an Accelerated Population Count, by Henry S. Warren, Jr., reveals the impact that some clever algorithms can have on even a seemingly simple problem.

Chapter 11, Secure Communication: The Technology of Freedom, by Ashish Gulhati, discusses the directed evolution of a secure messaging application that was designed to make sophisticated but often confusing cryptographic technology intuitively accessible to users.

Chapter 12, Growing Beautiful Code in BioPerl, by Lincoln Stein, shows how the combination of a flexible language and a custom-designed module can make it easy for people with modest programming skills to create powerful visualizations for their data.

Chapter 13, The Design of the Gene Sorter, by Jim Kent, combines simple building blocks to produce a robust and valuable tool for gene researchers.

Chapter 14, How Elegant Code Evolves With Hardware: The Case Of Gaussian Elimination, by Jack Dongarra and Piotr Luszczek, surveys the history of LINPACK and related major software packages, to show how assumptions must constantly be re-evaluated in the face of new computing architectures.

Chapter 15, The Long-Term Benefits of Beautiful Design, by Adam Kolawa, explains how attention to good design principles many decades ago helped CERN's widely used mathematical library (the predecessor of LINPACK) stand the test of time.

Chapter 16, The Linux Kernel Driver Model: The Benefits of Working Together, by Greg Kroah-Hartman, explains how many efforts by different collaborators to solve different problems led to the successful evolution of a complex, multithreaded system.

Chapter 17, Another Level of Indirection, by Diomidis Spinellis, shows how the flexibility and maintainability of the FreeBSD kernel is promoted by abstracting operations done in common by many drivers and filesystem modules.

Chapter 18, Python's Dictionary Implementation: Being All Things to All People, by Andrew Kuchling, explains how a careful design combined with accommodations for a few special cases allows a language feature to support many different uses.

Chapter 19, Multi-Dimensional Iterators in NumPy, by Travis E. Oliphant, takes you through the design steps that succeed in hiding complexity under a simple interface.

Chapter 20, A Highly Reliable Enterprise System for NASA's Mars Rover Mission, by Ronald Mak, uses industry standards, best practices, and Java technologies to meet the requirements of a NASA expedition where reliability cannot be in doubt.

Chapter 21, ERP5: Designing for Maximum Adaptability, by Rogerio Atem de Carvalho and Rafael Monnerat, shows how a powerful ERP system can be developed with free software tools and a flexible architecture.

Chapter 22, A Spoonful of Sewage, by Bryan Cantrill, lets the reader accompany the author through a hair-raising bug scare and a clever solution that violated expectations.

Chapter 23, Distributed Programming with MapReduce, by Jeff Dean and Sanjay Ghemawat, describes a system that provides an easy-to-use programming abstraction for large-scale distributed data processing at Google that automatically handles many difficult aspects of distributed computation, including automatic parallelization, load balancing, and failure handling.

Chapter 24, Beautiful Concurrency, by Simon Peyton Jones, removes much of the difficulty of parallel program through Software Transactional Memory, demonstrated here using Haskell.

Chapter 25, Syntactic Abstraction: The syntax-case Expander, by Kent Dybvig, shows how macros-a key feature of many languages and systems-can be protected in Scheme from producing erroneous output.

Chapter 26, Labor-Saving Architecture: An Object-Oriented Framework for Networked Software, by William Otte and Douglas C. Schmidt, applies a range of standard object-oriented design techniques, such as patterns and frameworks, to distributed logging to keep the system flexible and modular.

Chapter 27, Integrating Business Partners the RESTful Way, by Andrew Patzer, demonstrates a designer's respect for his programmers by matching the design of a B2B web service to its requirements.

Chapter 28, Beautiful Debugging, by Andreas Zeller, shows how a disciplined approach to validating code can reduce the time it takes to track down errors.

Chapter 29, Treating Code as an Essay, by Yukihiro Matsumoto, lays out some challenging principles that drove his design of the Ruby programming language, and that, by extension, will help produce better software in general.

Chapter 30, When a Button Is All That Connects You to the World, by Arun Mehta, takes you on a tour through the astounding interface design choices involved in a text editing system that allow people with severe motor disabilities, like Professor Stephen Hawking, to communicate via a computer.

Chapter 31, Emacspeak: The Complete Audio Desktop, by TV Raman, shows how Lisp's advice facility can be used with Emacs to address a general need-generating rich spoken output-that cuts across all aspects of the Emacs environment, without modifying the underlying source code of a large software system.

Chapter 32, Code in Motion, by Laura Wingerd and Christopher Seiwald, lists some simple rules that have unexpectedly strong impacts on programming accuracy.

Chapter 33, Writing Programs for "The Book," by Brian Hayes, explores the frustrations of solving a seemingly simple problem in computational geometry, and its surprising resolution.