Category Archives: development

Some lesser-known truths about programming

My experience as a programmer  has taught me a few things about writing software. Here are some things that people might find surprising about writing code:

  • Averaging over the lifetime of the project, a programmer spends about 10-20% of his time writing code, and most programmers write about 10-12 lines of code per day that goes into the final product, regardless of their skill level. Good programmers spend much of the other 90% thinking, researching, and experimenting to find the best design. Bad programmers spend much of that 90% debugging code by randomly making changes and seeing if they work.
  • A good programmer is ten times more productive than an average programmer. A great programmer is 20-100 times more productive than the average. This is not an exaggeration – studies since the 1960’s have consistently shown this. A bad programmer is not just unproductive – he will not only not get any work done, but create a lot of work and headaches for others to fix.

    “A great lathe operator commands several times the wage of an average lathe operator, but a great writer of software code is worth 10,000 times the price of an average software writer.” –Bill Gates

  • Great programmers spend little of their time writing code – at least code that ends up in the final product. Programmers who spend much of their time writing code are too lazy, too ignorant, or too arrogant to find existing solutions to old problems. Great programmers are masters at recognizing and reusing common patterns. Good programmers are not afraid to refactor (rewrite) their code  to reach the ideal design. Bad programmers write code which lacks conceptual integrity, non-redundancy, hierarchy, and patterns, and so is very difficult to refactor. It’s easier to throw away bad code and start over than to change it.
  • Software development obeys the laws of entropy, like any other process. Continuous change leads to software rot, which erodes the conceptual integrity of the original design. Software rot is unavoidable, but programmers who fail to take conceptual integrity into consideration create software that rots so so fast that it becomes worthless before it is even completed. Entropic failure of conceptual integrity is probably the most common reason for software project failure. (The second most common reason is delivering something other than what the customer wanted.) Software rot slows down progress exponentially, so many projects face exploding timelines and budgets before they are mercifully killed.
  • A 2004 study found that most software projects (51%) will fail in a critical aspect, and 15% will fail totally. This is an improvement since 1994, when 31% failed.
  • Although most software is made by teams, it is not a democratic activity. Usually, just one person is responsible for the design, and the rest of the team fills in the details.
  • Programming is hard work. It’s an intense mental activity. Good programmers think about their work 24/7. They write their most important code in the shower and in their dreams. Because the most important work is done away from a keyboard, software projects cannot be accelerated by spending more time in the office or adding more people to a project.

Xcode All-In-One View

One thing I don’t like about the default Xcode layout is that all the views – code, debug, console, find, etc open in new windows by default.

If you’d rather not manage a bunch of Xcode windows all the time,  Xcode has a “hidden” All-One-One view which shows all your views in a single window and ads a page toggle which conveniently switched between code and debugging toolbars.  You can access under Preferences – General – Layout.  This took me a long time to figure out because the Layout dropdown is disabled when a project is open.  Maybe it’s my Visual Studio background, but I like the integrated view much better.


Mises Tagging Overview

The framework used to tag pages on is a tagging library I developed to tag any kind of content on  The tag library references GUID‘s assigned to all objects in the databases.
It tracks users by username or IP address as well as the date that each tag was added.  It includes spam/bad word filtering and has some simple tag rewriting to automatically correct misspelled words and incomplete names.  For a simple tag example, see business cycle.

Update: Mises Tagging is now an open source project!  See the project page for details.

Architecture overview:

Database layer:

The database schema gives a good indication of the
data-access layer:

Tag Schema

Stored procedures:

UI Layer:

The interface is organized into self-contained user


  • DocumentTags.ascx – an editable list of tags for a particular
  • Tags.aspx: delete tags, delete all tags by a particular user
    and search/replace tags

The MisesBot:

You might have noticed that 99% of all tags are entered by
the MisesBot.  The bot is an application
that uses the meta tags collected by the MetaParser (detailed in a future post)
as well as other available metadata to add tags to document.

Thanks to:

  • Cloud Control for ASP.Net – displays a list of hyperlinks in
    varying styles depending on a weight.
  • Toxi – the inspiration for the tag schema
  • Freetag, an Open Source Tagging / Folksonomy module for
    PHP/MySQL applications – the inspiration for the business logic layer
  • Community Server –  Inspired the tag browser interface and provided the banned words list.

To do:

  • Did you notice the TagAuthority field in the tag
    schema?  A future version of the MisesBot
    will automatically determine the “authoritative” document for each tag.
  • Automatically mark up content.  If we know the authoritative document for a
    tag, we can automatically link to it when that tag appears in the document text.
  • Improving the “related tags” algorithm.  I could use some help with this:

Here is the query to get related tags.  The problem is that it currently ranks tags according to their total popularity, not their “related-ness.”

PROCEDURE [dbo].[TagGetRelatedTags]
        @Tag VARCHAR(70)
                @TagId int
                SET @TagId =
                        (SELECT TagId FROM Tag WHERE Tag = @Tag)
                        SELECT  TOP 30 Tag.Tag,
                                COUNT(TagMap.TagId) AS 'Count'
                        FROM    TagMap
                        INNER JOIN Tag
                        ON      TagMap.TagId    = Tag.TagId
                        WHERE   [TagMap].TagId <> @TagId
                            AND (TagMap.TagId  IN
                                (SELECT DISTINCT TagId
                                FROM    TagMap
                                WHERE (ObjectId IN
                                        (SELECT ObjectId FROM TagMap WHERE (TagId = @TagId)))
                        GROUP BY TagMap.TagId,
                        ORDER BY 'Count' DESC