<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>antonym</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/" />
    <link rel="self" type="application/atom+xml" href="http://antonym.org/atom.xml" />
    <id>tag:antonym.org,2008-10-28://2</id>
    <updated>2011-03-08T12:53:34Z</updated>
    <subtitle>whereupon Gavin Baker may write about the craft of software</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 5.01</generator>

<entry>
    <title>Good Code Gardening</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2011/03/good-code-gardening.html" />
    <id>tag:antonym.org,2011://2.161</id>

    <published>2011-03-08T12:09:57Z</published>
    <updated>2011-03-08T12:53:34Z</updated>

    <summary>During a code review at work recently, we had an interesting discussion about code maintenance. You could say that coding is a bit like gardening: while you are planting new seedlings, do you weed nearby areas as you go, or...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="Software Engineering" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>During a code review at work recently, we had an interesting discussion about code maintenance.  You could say that coding is a bit like gardening: while you are planting new seedlings, do you weed nearby areas as you go, or save up all the weeding for the next sunny weekend?  Should code maintenance be a continual, gradual process, or does it warrant being scheduled as a task in its own right?</p>
]]>
        <![CDATA[<p>First, let us define &#8220;code maintenance&#8221; as editing source code to make <em>non-functional changes</em>, such as:</p>

<ul>
<li>fixing formatting</li>
<li>fixing whitespace</li>
<li>improving consistency</li>
<li>correcting typos</li>
<li>commenting</li>
<li>minor refactoring</li>
<li>removing dead code</li>
</ul>

<p>In general, these sorts of changes are improving code hygiene, tasks which are not normally scheduled or allocated.</p>

<p>Now, the problem is this: imagine you are working on a large codebase, which has been around for quite some time, and has had a variety of authors modifying it.  As you are working on a new feature, you are adding new code, and refactoring existing code to enable the new code to work.  Suppose you come across some old, dead code. Should you remove it right now?  You see an obvious typo in an unrelated comment.  Should you correct it here?  You notice some inconsistently formatted code.  Should you update its layout before moving on with your main task?</p>

<p>There are only two answers to this seemingly simple question, but there are many important issues that surround it.  Either you fix it now (garden as you go), or save it for later (do it all on Weeding Day).</p>

<h2>Garden as you Go</h2>

<p>Why should do tidy your code as you go?</p>

<ul>
<li>You may forget to come back and do it later</li>
<li>You might run out of time to do later, as another bug or feature will take priority</li>
<li>A patch with a few extra whitespace changes or comment edits is trivial and takes hardly any time to review</li>
<li>As the code gradually expands, it is incrementally and constantly improved</li>
<li>Code hygiene improves code quality</li>
</ul>

<h2>Weeding Day</h2>

<p>Why should you do your weeding separately?</p>

<ul>
<li>Mixing code maintenance in with new code in a single patch obscures the actual intent, and the patch is no longer one discrete piece of work</li>
<li>Unrelated changes may make it more difficult to merge</li>
<li>Reviewing code for unrelated changes can waste reviewers&#8217; time</li>
<li>Maintenance is important, and should be scheduled as a discrete work item</li>
<li>Maintenance needs to make the code more consistent, so it should be done in one hit</li>
</ul>

<h2>The Verdict</h2>

<p>The conclusion I came to is a kind of compromise, but ultimately driven by the notion that the sanctity of the patch is the most important factor.  One patch should always be a discrete piece of work, so mixing new features and gardening/maintenance into one patch is a bad idea.</p>

<p><strong>But</strong> the argument that it is very hard to <em>schedule</em> maintenance time is a compelling one, as there is invariably a huge backlog of bug fixes or new features waiting which take priority.  With all the best intentions in the world, most managers will rather have you working on new features and bug fixes than touching code that already works.  So maintenance doesn&#8217;t get scheduled.</p>

<p>So if you don&#8217;t perform code maintenance as you go, when do you do it?  You do it as you go!  Let me explain&#8230;</p>

<p>You perform your code gardening/maintenance as you go, but you <strong>commit your maintenance changes separately</strong>.  Feature work goes into one patch (or changeset or commit), bug fixes go into their own patch (maybe with a regression test), and maintenance goes in its own patch.  That way, each patch can be reviewed without any distractions, merges are simpler, and you still get continual improvement.</p>

<h2>Howto: In Depth</h2>

<p>A good craftsperson has good tools, and my proposed solution requires good tool support to be truly effective.  Ideally, You will be using a powerful version control system (VCS) such as <a href="http://mercurial.selenic.com/">Mercurial</a> or <a href="http://git.kernel.org/">git</a> (unfortunately <a href="http://subversion.tigris.org/">Subversion</a> does not really do what we need, though it can be wrangled with some effort).  Both these tools allow you to check in changes not only at the level of an individual file, but at the level of changed <em>hunks within a file</em>.  This lets you more easily manage a <em>subset</em> of the current outstanding changes in your source tree.  So the idea is that you can go ahead and do maintenance all over the place, knowing your patch will end up nice and clean and separate from the maintenance work.</p>

<p>So how do you this?  Imagine you have a tool with the following files:</p>

<pre><code>fileio.c
fileio.h
parser.c
parser.h
main.c
utils.c
utils.h
</code></pre>

<p>You need to modify the file loading support to fix a bug with handling metadata in the headers.  So you modify <code>fileio.c</code> and <code>fileio.h</code>.  Along the way, you need to modify <code>render.c</code>, and along the way add some debug code to the rendering code.  This last change is of course throwaway test code that you will never check in.  And while you&#8217;re hacking away adding tracing statements, you notice some dodgy comments, which don&#8217;t match with the code.  So you fix those, and keep going - only to find someone managed to insert some hard tabs in there by mistake (after all, who would do that on <em>purpose</em>?).  So you use the Emacs <code>untabify</code> function to clean up that region too.  The renderer code uses some functions in the <code>utils</code> module, and you notice the docstring is missing an explanation of the parameters, so you add some <code>@param</code> statements while you&#8217;re there.  Now your VCS will give you the following status (Mercurial output):</p>

<pre><code>M fileio.c
M fileio.h
M render.c
  render.h
  main.c
  utils.c
M utils.h
</code></pre>

<p>And if you looked at the overall diff, it would mix in a bunch of unrelated changes in with your file loading fix.  You&#8217;re two degrees removed from the original problem by the time you get to <code>utils</code>.  But all these changes are worthwhile, and improve the code.  You don&#8217;t want to lose them.</p>

<p>So you simply don&#8217;t check in <code>utils.h</code> at all.  That&#8217;s easy (and even <code>svn</code> can cope with that).  And you commit all of the changes to <code>fileio</code>, as those make up the fix you were working on in the first place.  But what about <code>render.c</code>?  You&#8217;ve got no less than <em>three</em> types of changes in there:</p>

<ul>
<li>temporary debug code (that will be removed later)</li>
<li>maintenance changes (to fix up the comments and whitespace)</li>
<li>bug fix changes (part of the file I/O fix)</li>
</ul>

<p>If you&#8217;re using Mercurial (my DVCS of choice), you can use the <code>record</code> command (a built-in extension)
to easily check in individual hunks (sub-parts of diffs).  You use <code>record</code> much like commit, except instead of committing all your outstanding changes, it will interactively prompt you on a per-file and then a per-hunk basis.  You can nominate to include all of a file&#8217;s changes, skip it entirely, or choose hunks.  This way, you can add both the <code>fileio</code> files, skip <code>utils</code> and choose only the bug fix changes that ended up in <code>render.c</code>.</p>

<pre><code>$ hg record -m "Bug fix for #123, validate metadata type and length before loading"
</code></pre>

<p>You will end up with the changes <em>just</em> for the bugfix in this one commit, making it nice and easy to send off to review.  And then you have the other changes remaining:</p>

<pre><code>  fileio.c
  fileio.h
M render.c
  render.h
  main.c
  utils.c
M utils.h
</code></pre>

<p>which you can then selectively commit at your leisure.</p>

<p>The following animation shows this process for a single file:</p>

<p><img alt="Gardening.gif" src="http://antonym.org/Gardening.gif" width="393" height="385" class="mt-image-none" style="" /></p>

<p>If you&#8217;re using <code>git</code>, there is a command that performs essentially the same thing.  You need first to add your desired changes to the &#8220;index&#8221; (or staging area).  You can even stage changes as you go, which is a very powerful (though potentially confusing) model.  This is performed with:</p>

<pre><code>$ git add --interactive
</code></pre>

<p>Once you have chosen the hunks that make up the desired patch, you can commit what is in the staging area and the diff for that changeset will be nice and clean.</p>

<p>Fortunately, there&#8217;s also GUI support for these operations.  For example, the most excellent <a href="http://gitx.frim.nl/">GitX tool</a> allows you to not only select individual hunks for commit, you can even split up hunks and control which individual lines are committed (or staged).</p>

<p>This discussion highlights the need for good tools to support your workflows (rather than have your tool dictate your workflow).  Stay tuned for an upcoming article on &#8220;Coding vs Patching&#8221;, exploring the idea that the practice of coding is very much about shepherding clean patches from inception through to review and final merging.</p>

<p>So - go be a Good Gardener&#8230;</p>
]]>
    </content>
</entry>

<entry>
    <title>25 Tips for Intermediate Mercurial Users</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2010/04/25-tips-for-intermediate-mercurial-users.html" />
    <id>tag:antonym.org,2010://1.160</id>

    <published>2010-04-07T12:58:56Z</published>
    <updated>2010-04-07T13:08:00Z</updated>

    <summary>I recently read an interesting article by Andy Jeffries entitled 25 Tips for Intermediate Git Users (linked to via proggit) . It had lots of useful information condensed into bite-sized task-oriented chunks. I&apos;ve been using Mercurial for a while now,...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="VCS" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="mercurial" label="mercurial" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>I recently read an interesting article by Andy Jeffries entitled <a href="http://andyjeffries.co.uk/articles/25-tips-for-intermediate-git-users">25 Tips for Intermediate Git Users</a> (linked to via <a href="http://www.reddit.com/r/programming/">proggit</a>) .  It had lots of useful information condensed into bite-sized task-oriented chunks.</p>

<p>I've been using <a href="http://mercurial.selenic.com/">Mercurial</a> for a while now, so I thought I would write a similar set of tips by translating from <code>git</code> to the equivalent <code>hg</code> commands.  Thanks to Andy for blessing this translation work.  There may well be some mistakes herein - please leave a comment if you have any improvements or fixes to suggest.</p>
]]>
        <![CDATA[<h1>Basic Tips</h1>

<h2>1. First Steps After Install</h2>

<p>Once you have <a href="http://www.selenic.com/mercurial/download/">installed Mercurial</a>, you should create the <code>.hgrc</code> file in your home directory which contains your default user configuration.  This is where you can customize options and load additional <a href="http://www.selenic.com/mercurial/wiki/Extensions">extensions</a>.  The absolute minimum is to specify your name and email address, which is recorded in every commit you make:</p>

<pre><code>[ui]
username = Joe Coder &lt;joe@example.com&gt;
</code></pre>

<p>To enable extensions, add a section called <code>[extensions]</code> and list the names.  I would recommend the following extensions, which are incredibly useful.  Just add another section to your config file:</p>

<pre><code>[extensions]
graphlog=
pager=
color=
fetch=
record=
bookmarks=
</code></pre>

<p>To configure an extension, add a section with its name, and the options within.  For example, to configure the <code>pager</code> extension, you should configure it to not interfere with certain interactive commands.  Something like this:</p>

<pre><code>[pager]
pager = LESS='FSRX' less
ignore = version, help, update, serve, record
</code></pre>

<p>For complete information about this file, see:</p>

<pre><code>$ hg help config
</code></pre>

<h2>2. Mercurial is tree-based</h2>

<p>Mercurial stores its repository in the "revlog" format.  This is a tree of commits and their metadata, with each commit being uniquely identified by its the SHA-1 hash.</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="MercurialRevisionTreeExample.png" src="http://antonym.org/hg25/MercurialRevisionTreeExample.png" width="703" height="221" class="mt-image-none" style="" /></span></p>

<p>When you see a changeset in this format:</p>

<pre><code>4225:cf1a9b1f9bee
</code></pre>

<p>this is showing the simple revision number, <code>4225</code>, and the revision hash, <code>cf1a9b1f9bee</code>.  Either can be used to refer to a revision, and usually the first four characters of the hash are sufficient to uniquely identify a revision.</p>

<p>The simple revision number (akin to the sequentially numbered revisions in <code>svn</code>) is unique to a repository, but not necessarily across repository clones.</p>

<p>Tags are simply labels associated with a revision.  Named branches are stored in the changeset metadata, while bookmarks are much like local tags that move with each commit.</p>

<p>There is always one named branch in existence: <code>default</code>.  This is normally where mainline development occurs, and is equivalent to <code>trunk</code> in Subversion, or <code>master</code> in git.</p>

<h2>3. Two parents - of course!</h2>

<p>The <code>hg log</code> command lets you view the details of your commit history.  Normally each commit has one parent, which is the path up the tree.  But when you perform a <code>merge</code> operation, you are combining two branches of the tree together.  This is known as a "merge commit", and the changeset is recorded as having two parents, referring to the two branches that were merged.</p>

<p>For example, here is a commit from one of my repos showing r32 merging with r30, to produce r33:</p>

<pre><code>.
.
|
|
o    changeset:   33:9710bef2500e
|\   parent:      30:ad3a51b8aa18
| |  parent:      32:a3f98e81c19c
| |  user:        Gavin Baker &lt;gavinb@...&gt;
| |  date:        Mon Nov 09 07:47:15 2009 +1100
| |  summary:     Merged udp log work from deadlock branch
| |
| o  changeset:   32:a3f98e81c19c
| |  branch:      deadlock_gb
| |  user:        Gavin Baker &lt;gavinb@...&gt;
| |  date:        Mon Nov 09 07:43:51 2009 +1100
| |  summary:     Started adding udp logging
| |
. .
. .
</code></pre>

<h2>4. Merge conflicts</h2>

<p>Mercurial can be configured to use an external tool to process three-way merges.  For example, to use the popular <code>kdiff3</code> tool, add the following section to your <code>.hgrc</code>:</p>

<pre><code>[merge-tools]
# Override stock tool location
kdiff3.executable = ~/bin/kdiff3
# Specify command line
kdiff3.args = $base $local $other -o $output
# Give higher priority
kdiff3.priority = 1
</code></pre>

<p>If you don't have an external merging tool, mercurial will save the left and right versions of the files, and place conflict markers ("&lt;&lt;&lt;&lt;", "---", ">>>>") in the working copy.  It is up to you to then edit the file, resolve the conflict, and then resolve or commit your changes.  To mark a conflicted file as resolved:</p>

<pre><code>$ hg resolve -m main.c
</code></pre>

<p>To check the status of files involved in the merge:</p>

<pre><code>$ hg resolve -l
</code></pre>

<h1>Servers, Branching and Tagging</h1>

<h2>5. Remote servers</h2>

<p>In Mercurial, every repository is self-contained and includes the full history of the project.  When you <code>clone</code> a repository, the URI of the original is stored in the repository's own <code>hgrc</code> file (stored in the <code>.hg</code> directory at the root of the repository).  In the section labelled <code>paths</code>, an entry is created called <code>default</code>, which points to the original repo.  This way, you do not have to specify a URI for certain commands that involve remote repositories.</p>

<p>To see which changes have been made in the default remote repository since you last updated:</p>

<pre><code>hg incoming
</code></pre>

<p>To see which changes you have locally that have not yet been pushed to the default remote repository:</p>

<pre><code>hg outgoing
</code></pre>

<p>You can always add more entries to the remote server list by editing the <code>.hg/hgrc</code> file.  These are simply aliases for the full URI, which you can use along with commands that need a repository path.  For example, given the following entries in the <code>.hg/hgrc</code> of a given repo:</p>

<pre><code>[paths]
goog = http://code.google.com/p/golang/
exp = https://bitbucket.org/gavinb/golang-exp/
</code></pre>

<p>the following sets of commands are equivalent:</p>

<pre><code>$ hg incoming http://code.google.com/p/golang/
$ hg incoming goog

$ hg outgoing https://bitbucket.org/gavinb/golang-exp/
$ hg outgoing exp
</code></pre>

<p>Open questions:</p>

<ul>
<li>Is there an extension equivalent to <code>git remote</code> for managing paths?</li>
<li>How do you compare just a local and a remote branch (not the full set of changesets)?</li>
</ul>

<h2>6. Tagging</h2>

<p>In Mercurial, there are two types of tags: regular tags and local tags.  Regular tags are stored in the <code>.hgtags</code> file in the root of the repository, and are versioned just like any other file.  These tags are also therefore propagated to any remote servers.  You can list all the current tags with:</p>

<pre><code>$ hg tags
</code></pre>

<p>To add a regular tag to the current revision, you simply give it a name:</p>

<pre><code>$ hg tag version_1_3
</code></pre>

<p>To associate a tag with a specific revision, you use the <code>-r</code> option:</p>

<pre><code>$ hg tag -r 4a93 version_1_2_1
</code></pre>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="MercurialTaggingExample.png" src="http://antonym.org/hg25/MercurialTaggingExample.png" width="702" height="248" class="mt-image-none" style="" /></span></p>

<p>Once you have created a tag, you can use its name virtually anywhere you would normally specify a revision.  So after the above two operations, <code>hg tags</code> would show:</p>

<pre><code>tip                 152:01ae0a9083c3
version_1_3          79;08a49fb329a1
version_1_2_1        22:4a93c0e1aa0b
</code></pre>

<p>A local tag works in almost the same way, except local tags do not get copied between repositories when running a <code>push</code> or <code>pull</code>.  You create a local tag by specifying the <code>-l</code> flag:</p>

<pre><code>$ hg tag -l experimental
</code></pre>

<p>The <code>bookmarks</code> extension also provides a form of local tags, which move with the latest commit.  (Bookmarks are very much like git's cheap local branches, and a topic worth its own article.)</p>

<h2>7. Creating Branches</h2>

<p>Creating a named branch in Mercurial is a matter of simply specifying a branch name, which will be saved in the metadata of the next commit:</p>

<pre><code>$ hg branch bug_fix_5948
</code></pre>

<p>To switch between branches, use the <code>update</code> command with the branch name:</p>

<pre><code>$ hg update gui_changes_experimental
</code></pre>

<p>To display all the current branches, simply issue:</p>

<pre><code>$ hg branches
</code></pre>

<p>The following example shows a feature branch for the GUI, and another for the database layer.  These branches are periodically merged with default, where releases are made:</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="MercurialBranchingExample.png" src="http://antonym.org/hg25/MercurialBranchingExample.png" width="904" height="291" class="mt-image-none" style="" /></span></p>

<p>There are other types of branches too.  The simplest is an "anonymous" branch, which you can create simply by updating to an earlier revision, making some changes, and committing a new child revision.  This will result in a commit with two children - ie. a branch.  Steve Losh has written <a href="http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/">an excellent article on branching</a> which explains this in more detail.</p>

<h2>8. Merging Branches</h2>

<p>Once the work on your branch is complete, you will want to merge it back to the mainline of development (which is usually <code>default</code>).  To close the branch before you merge, use:</p>

<pre><code># on branch gui_changes_experimental
$ hg commit --close-branch -m "Experimental branch was a success"
</code></pre>

<p>Then you switch back to the target branch into which you want to merge your changes.</p>

<pre><code>$ hg update default
</code></pre>

<p>And then specify the name of the branch to merge, like this:</p>

<pre><code>$ hg merge gui_changes_experimental
</code></pre>

<p>Mercurial will then attempt to automatically merge all the changes, and notify you if there are any conflicts that require manual resolution.  At this point it can also launch a custom merging utility. (See tip #4 above.)</p>

<p>If you would like to see which changesets would be merged from a branch, you can preview the merge using:</p>

<pre><code>$ hg merge -P gui_changes_experimental
</code></pre>

<p>You can see a list of open branches using:</p>

<pre><code>$ hg branches
</code></pre>

<p>And you can see which changes have yet to be merged by doing a diff with the branch name:</p>

<pre><code># on branch default
hg diff gui_changes_experimental
</code></pre>

<h2>9. Remote branches</h2>

<p>By default, when you <code>push</code> your changes to a remote server, you push all commits made since the last update.  To push only a single branch, you can specify its name (or a given revision):</p>

<pre><code>$ hg push -r gui_changes_experimental
</code></pre>

<p>This will push all the changesets starting from the head of the branch, and all its ancestors that do not appear in the remote repository.</p>

<p>As far as I know, there is no direct equivalent to git's tracking branches in Mercurial.</p>

<h1>Storing Content in stashes, etc</h1>

<h2>10. Stashing</h2>

<p>If you are in the middle of a set of changes, and you need to perform an operation on the repository without first committing all of your local changes, you can "stash" them away and set them aside using the <a href="http://mercurial.selenic.com/wiki/ShelveExtension">shelve</a> extension.  This puts your current set of changes into a temporary storage area, from which you can restore them later.</p>

<p>To save your changes, run:</p>

<pre><code>$ hg shelve
</code></pre>

<p>You can interactively specify which changes to shelve at the granularity level of individual hunks, or simply stash entire files.  To bring your changes back into the working directory, simply use:</p>

<pre><code>$ hg unshelve
</code></pre>

<h2>11. Adding Interactively</h2>

<p>Ideally every commit should be a discrete patch that applies one cohesive change.  But for various real-world reasons, you often find yourself with a working directory that contains modified files containing multiple unrelated changes.  Sometimes it is individual files, sometimes even within the one file.  It would be great to be able to commit a subset of your patches, and choose individual hunks or files to commit.  The <code>record</code> extension does exactly that.  Running:</p>

<pre><code>$ hg record
</code></pre>

<p>interactively shows you each file, and lets you inspect each hunk that has changed, one by one.  You can accept individual hunks to commit, accept or ignore an entire file, and so on.  Any changes you do not commit will remain in your working copy to deal with later.  This is a great way to keep your commits clean and separate.</p>

<h2>12. Handling Large Files</h2>

<p>(There is no direct equivalent to the original list's item #12, "Storing/Retrieving from the Filesystem".)</p>

<p>Some projects (games are an excellent example) feature large binary resources, which do not lend themselves well to management under a VCS.  Examples include images, movies, sound files, level data, and so on.  You don't want to keep multiple versions of these files around if you can help it, and performance can suffer for files over about 10MB.</p>

<p>The <a href="http://mercurial.selenic.com/wiki/BigfilesExtension"><code>bigfile</code> extension</a> aims to solve this problem by storing large binary files (Binary Large Objects, or BLOBs) in a separate location, while still allowing you to manage the files using Mercurial.  A sample session looks like this:</p>

<p><em>*</em> TODO Insert bigfile example</p>

<h1>Logging and What Changed</h1>

<h2>13. Viewing a Log</h2>

<p>To review the details of your commit history, you use the <code>log</code> command.  A brief one-line summary is displayed with:</p>

<pre><code>$ hg log
</code></pre>

<p>To see the logs for a specific revision, range, tag or branch, use the <code>-r</code> switch:</p>

<pre><code>$ hg log -r9584
$ hg log -r release_1.3
</code></pre>

<p>To show all the details of the metadata, and the full commit message, use the verbose <code>-v</code> switch.</p>

<p>If you want to view the patch itself, use:</p>

<pre><code>$ hg log -p
</code></pre>

<p>If you enabled the <code>glog</code> extension (distributed with Mercurial), you can see a graphical representation (in ASCII art) of the commit tree, showing branches and merges using:</p>

<pre><code>$ hg glog
</code></pre>

<h2>14. Searching the Log</h2>

<p>To display only those changesets which have been committed by a given author, use the following command:</p>

<pre><code>$ hg log -u joe
</code></pre>

<p>You can search for a username, real name or in fact any substring in the 'author' field.</p>

<p>To search for a keyword that appears in the commit message, use:</p>

<pre><code>$ hg log -k regression
</code></pre>

<p>To search for commits that changed certain filenames, you can include or exclude patterns:</p>

<pre><code>$ hg log -I "**/Makefile"
$ hg log -X "*.xml"
</code></pre>

<p>To view all commits made since a given date:</p>

<pre><code>$ hg log -d "&gt;2009-11-1"
</code></pre>

<p>There are many more date options - see <code>hg help dates</code> for the full list.</p>

<p>The <code>log</code> command can also display the log output using a user-defined template, which can be very useful for scripting and custom reporting.  This example can be used to derive summary statistics of changed files by user:</p>

<pre><code>$ hg log --template "{date}|{user}|{diffstat}" -d "&gt;2009-11-20"
</code></pre>

<p>See <code>hg help templating</code> for the complete syntax.</p>

<h2>15. Selecting Revisions</h2>

<p>There are many ways of specifying a revision when using commands such as <code>log</code>, <code>merge</code>, and so on.</p>

<pre><code>$ hg log -r 4281               # By short revision number
$ hg log -r d1b75410b793       # By full revision number (SHA-1 hash)
$ hg log -r feature_213        # By branch name (refers to head of branch)
$ hg log -r release_1_31       # By tag name
$ hg log -r refactor_engine    # By bookmark name
</code></pre>

<p>If you install the <a href="http://mercurial.selenic.com/wiki/ParentrevspecExtension"><code>parentrevspec</code> extension</a>, you can also use git-style relative revisions, such as <code>foo^^</code> for the second parent of revision <code>foo</code>.</p>

<h2>16. Selecting a range</h2>

<p>To specify a range of revisions to a command taking a <code>-r</code> revision range, use the syntax <code>[BEGIN]:[END]</code>.  If <code>BEGIN</code> is not specified, it defaults to revision 0, and if <code>END</code> is not specified, the <code>tip</code> revision is used.  A single <code>:</code> by itself refers to all history.  You can even specify the revisions in reverse order, if <code>END</code> is less than <code>BEGIN</code>.  Again, a revision can be specified using any style as per tip #15 above.</p>

<h1>Rewinding Time and Fixing Mistakes</h1>

<h2>17. Resetting changes</h2>

<p>If you have modified a file in your working directory, but you wish to discard the changes and not commit them, you can use:</p>

<pre><code>$ hg revert parser.c
</code></pre>

<p>If you just committed a change that you didn't intend, you can back out that change.  (Note that this will only work if the commit was the very last transaction you applied.)  You run:</p>

<pre><code>$ hg rollback
</code></pre>

<p>The working copy will be back to where it was before the commit, and the commit will be deleted from the repository.</p>

<p>If you want to delete an entire branch, you can do so (provided you have the <code>mq</code> extension enabled) using:</p>

<pre><code>$ hg strip -r 432
</code></pre>

<p>This will remove revision 432 <em>and all its descendants</em> from the repository.  So it is just like pruning a branch from a tree.  Note that this is a very destructive operation!  For your safety, Mercurial will store the stripped changesets into a bundle, so you can reapply the bundle if you made a mistake.</p>

<p>The preferred way of undoing the effect of an older commit is to use:</p>

<pre><code>$ hg backout -r 9684
</code></pre>

<p>This will create a new changeset that reverses the effect of the specified revision.  It may create a new head (depending on the working directory's parent), in which case you can merge the new head into default.</p>

<h2>18. Committing to the wrong Branch</h2>

<p>If you've made a bunch of changes, then committed them to the wrong branch in multiple versions, all is not lost.  While <code>hg rollback</code> will undo the last transaction (ie. commit), it cannot reverse more.</p>

<p>If you want to undo the changes in one changeset, use:</p>

<pre><code>$ hg backout
</code></pre>

<p>which will create a new changeset that reverses the effect of the specified revision.  This will normally create a new head, so you will need to merge this into <code>tip</code>.</p>

<p>If you have committed a series of changesets, you could also run <code>hg strip</code> from the errant revision to remove it from the tree.  Then switch to the correct branch, take the bundle file that <code>strip</code> saves for you, and apply the bundle.</p>

<h2>19. Interactive Rebasing</h2>

<p>The <a href="http://mercurial.selenic.com/wiki/HisteditExtension"><code>histedit</code> extension</a> provides similar functionality to git's powerful <code>rebase --interactive</code> command.  It allows you to take a series of changesets, and commit, fold into a previous commit, edit or drop each revision.  It will then reorder and reapply the changesets in the specified manner.</p>

<p>This can be useful for cleaning up a feature branch before merging, for example.  Note that this does involve modifying existing changesets, so be careful to do it before pushing the changes to another repo.</p>

<h2>20. Cleaning up</h2>

<p>To clean up your working directory and remove files not under version control, you can display a list of untracked files (<code>-u</code>) without displaying the status (<code>-n</code>), then pipe the results to a command to delete them:</p>

<pre><code>$ hg st -nu | xargs rm
</code></pre>

<p>If you want to clear away all the files in your working directory (but otherwise leave your repository intact) use:</p>

<pre><code>$ hg checkout null
</code></pre>

<p>All tracked files will be removed, leaving your working copy empty (but of course the repository still intact).  This can be useful on servers, in clones, and to save space in older projects.</p>

<h1>Miscellaneous Tips</h1>

<h2>21. Previous References You've Viewed</h2>

<p>(This doesn't apply to hg.)</p>

<h2>22. Branch Naming</h2>

<p>Branch names can contain the usual characters, such as a-z, A-Z and numeric characters.  But you can also use other punctuation characters, so you can create a psueo-namespace:</p>

<pre><code>$ hg branch experimental/parsing_performance
</code></pre>

<h2>23. Finding Who Dunnit</h2>

<p>It can be very useful to see who made a particular change in a file.  The <code>annotate</code> command will display a file, and annotate each line with the revision and author of the last modification.  (This command is often known as the <code>blame</code> command, as you probably want to know who broke the build.)</p>

<h2>24. Repository Maintenance</h2>

<p>The Mercurial repository format ("reflog") is designed to be reliable and efficient.  Unlike the git storage format, it does not require ongoing maintenance (such as garbage collection).</p>

<p>Since file systems and hard drives are fallible, it is possible that an error could corrupt a repository.  To verify the integrity of the repository, run:</p>

<pre><code>$ hg verify
</code></pre>

<p>This will perform an extensive series of tests, and report the results.</p>

<h2>25. Ignore files by pattern</h2>

<p>Your working directory can often become cluttered with generated or intermediate files that you do not want to check in to your repository.  You can add a list of files to ignore, either for all repos (by adding it to your <code>~/.hgrc</code>) or selectively for a given repository (by editing <code>.hgignore</code> in the root of your repo).  You can use either a simple globbing form, or a full regexp specification.  Here's an example:</p>

<pre><code>syntax:glob
*.o
*.a
*.dylib
*.pyc
*.res
*~
</code></pre>

<p>This tells Mercurial to simply ignore these files.  If you are using Xcode, you will want to exclude the build product tree entirely, and also the per-user project settings (which change frequently and don't really need to be under version control):</p>

<pre><code>build/*
MyProject.xcodeproj/*.pbxuser
MyProject.xcodeproj/*.mode1v3
</code></pre>

<h2>26. Bonus: Built-in Web Server</h2>

<p>Thanks to its Python foundation, Mercurial features a built-in web server.  You can browse the revision history, review metadata, display a graphical timeline view, list tags and branches, and view file lists and contents.  It is fully configurable, with different styles and templates.  But to get up and running very quickly, simply run the following command:</p>

<pre><code>$ hg serve -d -n myproject
</code></pre>

<p>The <code>-d</code> will daemonise the server, which will run it in the background.  By default, the server listens on port 8000, so simply fire up your browser and point it to:</p>

<pre><code>http://localhost:8000/
</code></pre>

<p>and that's it!  You can run multiple instances, install it alongside Apache, and have it run a webdir serving multiple repositories.  It's very powerful and useful.</p>

<h1>Closing</h1>

<p>I hope this is a useful set of tips.  Thanks again to Andy for the original <code>git</code> document.  Please leave a comment or drop me an email if you have any suggestions or improvements for the above.</p>
]]>
    </content>
</entry>

<entry>
    <title>Threading with Boost - Part II: Threading Challenges</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2010/01/threading-with-boost---part-ii-threading-challenges.html" />
    <id>tag:antonym.org,2010://1.159</id>

    <published>2010-01-01T09:15:20Z</published>
    <updated>2010-01-01T09:27:19Z</updated>

    <summary>In Part I of this series on Boost, we looked at the basics of how to create and run threads using the Boost libraries. But once you have more than one thread running in a process, you have to deal...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="Boost" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C++ Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="boost" label="boost" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mutexes" label="mutexes" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>In <a href="http://antonym.org/">Part I</a> of this series on <a href="http://boost.org/">Boost</a>, we looked at the basics of how to create and run threads using the Boost libraries.  But once you have more than one thread running in a process, you have to deal with the problems and challenges that threads can introduce.  So, before delving into the mechanics of how to use mutexes and other threading constructs, we look at what can go wrong - and how to avoid it.</p>
]]>
        <![CDATA[<h1>Shared State</h1>

<p>There is a simple solution to most major threading problems: have no shared state.  By shared state, I mean any data or resource (such as file handle, socket, graphics context, queue, buffer, etc) that is used by more than one thread at the same time.  If two threads are truly independent, they can safely run concurrently without care or consideration.  We wouldn't need sophisticated mechanisms for synchronisation if there's nothing to sync over.  Unfortunately, this restriction is not at all practical or realistic.  And as soon as you introduce shared state, you have to worry about atomicity, consistency, race conditions, and all sorts of issues.</p>

<p>So one of the first design considerations for concurrent systems is to try to minimise the amount of shared state between threads.  The less shared state, the less complexity there is to manage, and the less overhead imposed. Locks that protect shared resources can harm performance: each lock is a region that enforces sequential access, and thus reduces the opportunities for concurrent scheduling.</p>

<p>Simply put, any resource shared between more than one thread needs to be protected by a mutex, such that access is serialised.</p>

<p>When considering scalability, the theoretical maximum speedup of N cores is always less than N times, due to scheduling and synchronisation overheads.  Thus the most efficient algorithm designs consider these issues up front.</p>

<h1>Problem: Atomicity</h1>

<p>An operation is <em>atomic</em> if the operation completes without interruption.  It is never partially complete, which may leave the system or data in an inconsistent or invalid state.  Atomic operations come up all over the place, and even things that we might <em>think</em> are atomic (ie. a single line in your source) probably isn't.  In databases, we use SQL transactions to ensure operations are atomic, such that a related set of changes are never partially applied.</p>

<p>The classic example of an atomic operation in a database is a bank transfer.  You decide to pay your landlord by direct deposit, and transfer $1200 to their account.  The normal sequence of operations is:</p>

<ol>
<li>Ensure you have sufficient funds</li>
<li>Ensure the receiving account number is valid</li>
<li>Withdraw the $1200 in funds from your account</li>
<li>Deposit the $1200 in the landlord's account</li>
</ol>

<p>Now the first two steps are really preconditions, and while they are necessary for the entire operation's success, if the operation was cancelled after step 1 or step 2, there would be no harm done, and nothing changed.  But once the money comes out of your account after step 3, you absolutely want step 4 to complete, otherwise you are $1200 out of pocket and you <em>still</em> owe the rent!  So steps 3 and 4 <em>must</em> either both happen successfully, or not at all.  If the network goes down between steps 3 and 4 such that the deposit cannot complete, you want to undo the withdrawal and try again later.  Steps 3 and 4 must be performed atomically.</p>

<p>While this example traditionally applies to database operations (and is thus resolved on-disk), the same concept applies to in-memory operations that must be atomic.  A <em>mutex</em> (for "mutual exclusion") or <em>critical section</em> can be used to serialise access to resources within a region of code that must run as an atomic operation. We would lock the mutex before the transaction, and unlock it afterwards.</p>

<h1>Problem: Race Conditions</h1>

<p>A <em>race condition</em> is a general term for a class of problems, whereby the result of an operation is at the mercy of the timing of concurrent events (typically unknown or effectively random).  This is bad because your program becomes non-deterministic - it may not always produce the correct result!  They represent one of the most subtle and difficult to debug problems in software development, which is one of the main reasons why multi-threaded programming is considered difficult.</p>

<h2>Example: A Counter</h2>

<p>Even a simple increment operation, which is only a single operation in C++, may actually be the source of a race condition.  Consider:</p>

<p><textarea name="code" class="c++" cols="60" rows="1">
    m_SequenceNumber++;
</textarea></p>

<p>which actually translates (on the x86 architecture) to something like:</p>

<p><textarea name="code" class="c++" cols="60" rows="3">
    movl    -12(%ebp), %eax
    incl    %eax
    movl    %eax, -12(%ebp)
</textarea></p>

<p>which is a load, increment, then store.  So there are actually <em>two</em> potential points that a race condition could occur - between the load and the increment, and between the increment and the save.</p>

<p>Now imagine two threads, which are both using a shared object.  If both threads happen to call the method that performs the increment method at the same time, one thread could be preempted in the middle, such that the instructions are interleaved.  So for threads A and B incrementing the sequence number, thus:</p>

<table>
  <thead>
    <th>Thread</th>
    <th>Instruction</th>
    <th>m_SequenceNumber</th>
    <th>Register</th>
  </thead>
  <tbody>
    <tr><td>A</td><td><tt>LOAD m_SequenceNumber, R0</tt></td><td>234</td><td>234</td></tr>
    <tr><td>A</td><td><tt>INCR R0</tt></td><td> 234 </td><td> 235</td></tr>
    <tr><td>B</td><td><tt>LOAD m_SequenceNumber, R1</tt></td><td>234</td><td>234</td></tr>
    <tr><td>B</td><td><tt>INCR R1</tt></td><td> 234 </td><td> 235</td></tr>
    <tr><td>B</td><td><tt>STORE R1, m_SequenceNumber</tt></td><td>235</td><td>235</td></tr>
    <tr><td>A</td><td><tt>STORE R0, m_SequenceNumber</tt></td><td>235</td><td>235</td></tr>
  </tbody>
</table>

<p>So, instead of the sequence number being incremented twice, and being 236 as we would expect, the sequence number is only 235.  This is a subtle, nasty and rare bug and could be very difficult to track down for the unprepared.</p>

<p>Fortunately, there is a nice, simple solution to this particular problem.  Operating systems provide atomic functions for safely performing an increment (with a minimum of overhead), as well as a few other common operations.  Under Windows, you would use the <a href="http://msdn.microsoft.com/en-us/library/ms683614(VS.85).aspx">InterlockedIncrement()</a>, while under Mac OS X you would call <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man3/OSAtomicIncrement32.3.html">OSAtomicIncrement32()</a>.  Under Linux, gcc provides <a href="http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html">__sync_fetch_and_add()</a> and friends.</p>

<h2>Example: Accessing a Queue</h2>

<p>An illustration of a race condition is where multiple threads are removing work items from a queue.  Imagine some code that looks something like this:</p>

<p><textarea name="code" class="c++" cols="60" rows="12">
    void unsafeWorkerThread()
    {
        while ( unsafeWorkerThreadRunning )
        {
            // Warning: this is not thread-safe!
            if ( !queue.isEmpty() )
            {
                work_t item = queue.pop();
                process(item);
            }
        }
    }
</textarea></p>

<p>This is not thread-safe!  Even if we assume that the queue operations themselves are atomic (which is usually <em>not</em> the case for most container classes!), there is a race condition waiting to trigger a failure.  Can you spot it?</p>

<p>Imagine there are two threads running, and there is one work item in the queue.  When <code>thread_A</code> calls <code>queue.isEmpty()</code>, it goes into the <code>if</code> block, as there is more data to process.  But then the thread is pre-empted, and <code>thread_B</code> gets a chance to run.  This time, it removes the work item and processes it.  But now the queue is empty, and <code>thread_A</code> thinks it isn't!  When <code>thread_A</code> resumes, it will call <code>queue.pop()</code> and trigger a stack underflow exception.  (And here, without a <code>try-catch</code> block, an exception would also cause the thread to exit without notice.) Now this code could run perfectly well for thousands of iterations, and never trigger these particular failure conditions.  But every so often, the timing will be just right (or rather wrong!) and your application will mysteriously fail.  You can see why many people say threading should be avoided at all costs!  The code is valid, usually works but every so often it fails in an unusual way.</p>

<p>The simplest solution is to protect the queue with a mutex, and lock it around the inner block.  (There's another improvement we can make after we discuss exceptions.)</p>

<p><textarea name="code" class="c++" cols="60" rows="15">
    void workerThread()
    {
        while ( workerThreadRunning )
        {
            queueMutex.lock();
            &nbsp;
            if ( !queue.isEmpty() )
            {
                work_t item = queue.pop();
                process(item);
            }
            &nbsp;
            queueMutex.unlock();
        }
    }
</textarea></p>

<p>(There are more esoteric solutions to this problem, such as lock-free data structures, but those are beyond the scope of this series.)</p>

<h1>Problem: Deadlocks</h1>

<p>In a non-trivial application, there may be several threads and numerous mutexes.  When more than one thread locks more than one mutex, there arises the potential for a condition known as a <em>deadlock</em>.  This is where one thread is holding a lock while waiting for another to become available, while a second thread is holding the second lock and waiting for the first lock to become available.  Since they are both waiting for each other to finish, neither can run.  This deadlocked situation can be more involved, whereby several threads form a ring of holding and waiting for locks.  This is illustrated as follows, first in code then as a diagram:</p>

<p><textarea name="code" class="c++" cols="60" rows="22">
    void threadA()
    {
        while (running)
        {
            mutexOne.lock();
            mutexTwo.lock();
            processStuff();
            mutexOne.unlock();
            mutexTwo.unlock();
        }
    }
    void threadB()
    {
        while (running)
        {
            mutexTwo.lock();
            mutexOne.lock();
            processStuff();
            mutexTwo.unlock();
            mutexOne.unlock();
        }
    }
</textarea></p>

<p><img src="http://antonym.org/boost/DeadlockAnimation.gif" alt="DeadlockAnimation.gif" border="0" width="561" height="249" /></p>

<p>Fortunately, the problem of deadlocks can largely be avoided by consistently locking mutexes in the same order, and unlocking them in reverse order.</p>

<h1>Problem: Exceptions</h1>

<p>Exceptions in C++ can be a very effective mechanism for error handling.  However, like many C++ features, care must be taken, especially in threads.  Because a thread is destroyed when the thread function returns, an uncaught exception can cause the entire thread to exit, without warning or notice.  So if you have a thread that mysteriously disappears, an uncaught exception is a likely culprit.</p>

<p>As with non-threaded code, you should always catch the most specific exception type that you are able to handle.  But if you wish to avoid your thread being killed, you should add a top-level <code>try-catch</code> block.  At this point, depending on the application, you may simply log the uncaught exception then exit, or you may resume thread processing (but only if safe to do so!).</p>

<p>A skeleton thread function might look something like:</p>

<p><textarea name="code" class="c++" cols="60" rows="16">
    void processThread()
    {
        while(keepProcessing)
        {
            try
            {
                // Do actual work
            }
            // Catch more specific exceptions first if you can
            catch (std::exception&amp; exc)
            {
                log("Uncaught exception: " + exc.what());
                // Maybe return here?
            }
        }
    }
</textarea></p>

<p>Just as an errant exception can cause havoc with threads running, they can also cause problems with mutexes.  The next article shows how to use a <em>lock guard</em> to ensure mutexes are unlocked, even if an exception is thrown.</p>

<h1>Other Problems</h1>

<p>Just to reinforce the idea that multithreaded programming is not a trivial undertaking, there are even more traps for the unwary, for which there is not sufficient time to delve into here.  Issues such as <a href="http://en.wikipedia.org/wiki/Resource_starvation">starvation</a>, <a href="http://en.wikipedia.org/wiki/Priority_inversion">priority inversion</a>, and high scheduling latency are all considerations for <a href="http://en.wikipedia.org/wiki/Concurrent_programming">concurrent programming</a>.  It is definitely worth consulting a good book or three.</p>

<h1>Closing thoughts</h1>

<p>Fortunately, there are well-known solutions to multi-threaded design issues, so it is entirely possible to write robust threaded code, provided one is careful and thoughtful.  Much of it starts with:</p>

<ul>
<li><strong>Minimise shared state</strong></li>
</ul>

<p>In days gone by, a multi-threaded system would often still only be running on a single core.  Certain classes of concurrency bugs were far less likely to happen.  But now multicore systems are standard, and we have truly concurrent execution, which brings into the fray problems such as memory consistency, cache latency, write-throughs, and so on.</p>

<p>Especially now that multicore systems are shipping as standard on desktops and laptops, concurrent programming is required to take advantage of the available processing resources.  So a thorough understanding of multithreading is increasingly important.</p>

<p>Some takeaway points to remember:</p>

<ul>
<li>Minimise shared state</li>
<li>Program defensively</li>
<li>Assume your threading code can be preempted at <em>any</em> time</li>
<li>Identify shared resources and protect them with mutexes</li>
<li>Identify algorithms that need to be atomic</li>
<li>Identify code with dependent results that needs to be atomic</li>
<li>Minimise the number of resources shared between threads</li>
<li>Minimise the duration of locks</li>
<li>Ensure exceptions cannot disrupt synchronisation flow</li>
<li>Always acquire and release mutexes in the same order</li>
</ul>

<p>The next article looks at the types of mutexes, and how to use them.</p>
]]>
    </content>
</entry>

<entry>
    <title>STL: filtering</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2009/09/stl-filtering.html" />
    <id>tag:antonym.org,2009://1.158</id>

    <published>2009-09-16T12:51:35Z</published>
    <updated>2009-09-16T14:18:14Z</updated>

    <summary>The STL makes it easy to create lists, iterate over lists, and apply a function to each member of a list. So how do you filter a vector according to some criteria? It&apos;s not hard, but the obvious solution isn&apos;t...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="C++ Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>The STL makes it easy to create lists, iterate over lists, and apply a function to each member of a list.  So how do you filter a vector according to some criteria?  It's not hard, but the obvious solution isn't <em>quite</em> enough.  Here's how.</p>
]]>
        <![CDATA[<p>Say you have a vector of values, and you want to apply a filter to the list.  That is,  remove elements that satisfy some criteria.  It's quite a common requirement, so you'd think there would be an obvious and simple way to do it.  If you go searching for the word "filter" in the STL documentation, you may not find much relevant in the <code>std::vector</code> method reference.  If you browse around in STL algorithms, eventually you'll come across a method called <code>remove_if</code>.  It takes two iterators to specify the range (first and last) of the operation, and a predicate function.  Sounds perfect!</p>

<p>Let's use it to filter a list of numbers, removing even numbers.  Given the following input:</p>

<pre><code>1 2 3 4 5 6 7 8 9
</code></pre>

<p>we expect to see the result:</p>

<pre><code>1 3 5 7 9
</code></pre>

<p>A predicate function is essentially a test for a property, and returns whether or not the parameter has this property.  So our predicate function will take an integer value (matching the element type of our vector) and return a boolean, denoting whether or not to remove the given element.  So we'd have:</p>

<p><textarea name="code" class="c++" cols="60" rows="4">
bool is_even(int N)
{
    return N % 2 == 0;
}
</textarea></p>

<p>Easy!  Now, to store our numbers, we would start with a simple vector of integers, thus:</p>

<p><textarea name="code" class="c++" cols="60" rows="3">
typedef std::vector<int> vector<em>t;
&nbsp;
vector</em>t    numbers;
</textarea></p>

<p>We read in the numbers in a loop and save them in the array:</p>

<p><textarea name="code" class="c++" cols="60" rows="11">
    while (true)
    {
        int n;
        &nbsp;
        std::cin >> n;
        &nbsp;
        if (!std::cin.good())
            break;
        &nbsp;
        numbers.push_back(n);
    }
</textarea></p>

<p>This will take care of reading in the data, as it will stop as soon as it reads something that isn't an integer, or reaches the end of file.  Now we just apply the filter, and then print the result:</p>

<p><textarea name="code" class="c++" cols="60" rows="7">
    remove<em>if(numbers.begin(), numbers.end(), is</em>even);
    &nbsp;
    vector_t::iterator it;
    for (it = numbers.begin(); it != numbers.end(); ++it)
    {
        std::cout &lt;&lt; *it &lt;&lt; std::endl;
    }
</textarea></p>

<p>There, we're done!  Now, we just run the completed program, and give it some test data:</p>

<pre><code>$ ./filter 
1 2 3 4 5 6 7 8 9 -
</code></pre>

<p>But wait, the output we see is wrong!</p>

<pre><code>1
3
5
7
9
6
7
8
9
</code></pre>

<p>Oh, no!  There must be a bug in the libraries!  Curses, foiled again!</p>

<p>Actually, no - the sky isn't falling, and there is no bug.  Now is when we probably should be doing a bit of RTFMing.  Let's check the docs and see what's going on.  According to the <a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/">g++ library documentation</a>:</p>

<blockquote>
  <p>"Elements between the end of the resulting sequence and 'last' are still present, but their value is unspecified."</p>
</blockquote>

<p>Er, ok... that's handy - not.  Looking back at the output, we do notice that the first 5 values are correct, but there's some junk after them.  And sure enough, that's the documented behaviour - we are just seeing the "unspecified" values left behind.</p>

<p>It is worth pointing out right about now that the fine folk who designed the STL were fairly obsessed with efficiency, and the STL is designed to be low-level, powerful and fast, sometimes at the expense of user friendliness.  It is more efficient to implement filtering as a generic algorithm that can be applied to any container.  And sure enough, that is the intent, as we see in the docs:</p>

<blockquote>
  <p>"@return   An iterator designating the end of the resulting sequence."</p>
</blockquote>

<p>Ah, we were actually supposed to do something with the return value!  The implementation of <code>remove_if</code> moves (or actually copies) the values to be kept to the head of the list, and returns an iterator pointing to the start of the "junk" (just after the filtered list), in preparation for this tail to be snipped off.  So, let's use the <code>erase</code> method to do just that:</p>

<p><textarea name="code" class="c++" cols="60" rows="1">
    numbers.erase(remove<em>if(numbers.begin(), numbers.end(), is</em>even), numbers.end());
</textarea></p>

<p>Now, running the test application again, we get the output:</p>

<pre><code>1
3
5
7
9
</code></pre>

<p>Huzzah!  It is really a matter of getting a feel for the design patterns behind the STL, and the very low-level API that it provides.</p>

<p>This process can be visualised thus:</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="STL Filtering Example" src="http://antonym.org/images/STLFilteringExample.png" width="532" height="670" class="mt-image-none" style="" /></span></p>

<p>It is also worth mentioning at this point that if you are doing a lot of adding and removing of  elements, a <code>std::list</code> is probably a better choice, as inserting and deleting elements in vectors is very expensive.</p>

<p>Now, you're probably wondering why <code>remove_if</code> is a function in the STL <code>algorithms</code> collection, rather than a method in <code>std::vector</code> itself.  Well, the folks who designed the STL are very, very clever.  The obvious thing would be to put a <code>remove_if</code> method in every single container class.  But the implementation would be <em>almost</em> the same, right?  Well, they reasoned, what if all container classes provided a common, minimal interface, we could implement <code>remove_if</code> just once, and it could apply to almost any container!  It's even more generic that way.  So there are a whole series of algorithms that apply to a wide variety of different containers, and use informal interfaces to decouple things.</p>

<p>The (platform-neutral) sample code is available below...</p>

<ul>
<li>Sample C++ code: <span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://antonym.org/files/stl_filter.zip">stl_filter.zip</a></span> (4.5kB zip)</li>
</ul>
]]>
    </content>
</entry>

<entry>
    <title>Threading with Boost - Part I: Creating Threads</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads.html" />
    <id>tag:antonym.org,2009://1.157</id>

    <published>2009-05-13T11:16:06Z</published>
    <updated>2010-02-26T21:37:45Z</updated>

    <summary>Boost is an incredibly powerful collection of portable class libraries for C++. There are classes for such tasks as date/time manipulation, filesystem interfaces, networking, numerical programming, interprocess communication and much more. The Boost documentation is substantial, but can still be...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="Boost" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C++ Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="boost" label="boost" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="c" label="c++" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p><a href="http://www.boost.org/">Boost</a> is an incredibly powerful collection of portable class libraries for C++.  There are classes for such tasks as date/time manipulation, filesystem interfaces, networking, numerical programming, interprocess communication and <a href="http://www.boost.org/doc/libs">much more</a>.</p>

<p>The Boost documentation is substantial, but can still be daunting to new users.  So this article is the first of a series on using Boost, starting with basic threading.  It aims to provide an accessible introduction, with complete working examples.</p>
]]>
        <![CDATA[<p>First, this article assumes you know about general threading concepts and the basics of how to use them on your platform.  (For a refresher, see the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Thread_(computer_science">Threads</a>).)  Here I focus specifically on how to use <a href="http://www.boost.org/doc/libs/1_39_0/doc/html/thread.html">Boost threads</a> in a practical setting, starting from the basics.  I also assume you have Boost installed and ready to use (see the Boost <a href="http://www.boost.org/doc/libs/1_39_0/more/getting_started/index.html">Getting Started Guide</a> for details).</p>

<p>This article looks specifically at the different ways to <em>create</em> threads.  There are many other techniques necessary for real multi-threaded systems, such as synchronisation and mutual exclusion, which will be covered in a future article.</p>

<h2>Overview</h2>

<p>A <code>boost::thread</code> object represents a single thread of execution, as you would normally create and manage using your operating system specific interfaces.  For example: on POSIX systems, a Boost thread uses the <code>Pthreads</code> API, and on Win32 it uses the native <code>CreateThread</code> and related calls.  Because Boost abstracts away all the platform-specific code, you can easily write sophisticated and portable code that runs across all major platforms.  A thread object can be set to a special state of not-a-thread, in which case it is inactive (or hasn't been given a thread function to run yet).</p>

<p>A <code>boost::thread</code> object is normally constructed by passing the threading function or method it is to run.  There are actually a number of different ways to do so.  I cover the main thread creation approaches below.</p>

<h2>Code Examples</h2>

<p>All the code examples are provided in a single download below, which you can use for any purpose, no strings attached.  (The usual disclaimer is that no warranties apply!)  And just as Boost runs on many platforms (ie. Windows, Unix/Linux, Mac OS X and others) the example code should be similarly portable.</p>

<ul>
<li>Download <span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://antonym.org/boost/boost_threads_eg1.zip"><code>boost_threads_eg1.zip</code></a> (4kB)</span></li>
</ul>

<p>There is a separate example program for each section below, and a common Bjam script to build them all (<code>Jamroot</code>).  <a href="http://www.boost.org/boost-build2/doc/html/index.html">Bjam</a> is the Boost build system, a very powerful (but notoriously difficult to learn, and worthy of a whole series of articles).</p>

<p>Having said that, you are certainly not obliged to use Bjam.  It is still worth knowing how to build applications manually before relying on scripts, so here is an example command line for manual compilation on my system (Mac OS X with Boost installed from MacPorts):</p>

<pre><code>g++ -I/opt/local/include -L/opt/local/lib -lboost_thread-mt -o t1 t1.cpp
</code></pre>

<p>All this does is add an include path (with the <code>-I</code> option) pointing to the root of the boost headers, add the library search path (with the <code>-L</code> option) and link in the threading library (<code>boost_thread-mt</code>).  You can use the above as the basis for writing our own Makefile if you prefer, or creating build rules in your IDE of choice.</p>

<h2>Doing 'Real' Work</h2>

<p>And before we dive in, a quick note on doing "real work"... In the examples below, a simple sleep call is used to simulate performing actual work in the threads.  This is simply to avoid cluttering up the examples with code that would take some finite time to execute but would otherwise be irrelevant.</p>

<p>The simplest way to sleep for a given duration using Boost is to first create a time duration object, and then pass this to the <code>sleep</code> method of the special <code>boost::this_thread</code> class.  The <code>this_thread</code> class gives us a convenient way to refer to the currently running thread, when we otherwise may not be able to access it directly (ie. within an arbitrary function).  Here's how to sleep for a few seconds:</p>

<p><textarea name="code" class="c++" cols="60" rows="4">
    // Three seconds of pure, hard work!
    boost::posix_time::seconds workTime(3);
    boost::this_thread::sleep(workTime);
</textarea></p>

<p>In the <code>main()</code> function, we then wait for the worker thread to complete using the <code>join()</code> method.  This will cause the main thread to sleep until the worker thread completes (successfully or otherwise).</p>

<p>The observant reader will wonder then what the advantage is in spawning a thread, only to wait for it to complete?  Surely that serialises the execution path and places us firmly back in sequential world?  What is the point of spawning a thread?  Well, until we figure out how to use the synchronisation mechanisms, this is the most straightforward approach to illustrate thread creation.  And knowing ow to 'join' threads is also very important.  To synchronise the completion of a thread, we wait for it to finish by calling <code>workerThread.join()</code>.</p>

<p>The general structure of the examples below is shown in the following sequence diagram:</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="BoostThreadExample.png" src="http://antonym.org/boost/BoostThreadExample.png" width="410" height="462" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></p>

<p>The application starts, and the main thread runs at (a).  Then at (b), the main thread spawns the worker thread by constructing a thread object with the worker function.  Right after, at (c), the main thread calls <code>join</code> on the thread, which means it will go to sleep (and not consume any CPU time) until the worker thread has completed.  As soon as the worker thread is created at (b), it will start execution.  At some point later at (d), the worker completes.  Since the main thread was joining on its completion, main wakes up and continues running.  It finishes at (e) and the process terminates.  Each of the examples below follow this general scheme - the difference lies in how the threads are created.</p>

<h2>Type 1: A Thread Function</h2>

<p>The simplest threading scenario is where you have a simple (C-style) function that you want to run as a separate thread.  You just pass the function to the <code>boost::thread</code> constructor, and it will start running.  You can then wait for the thread to complete by calling <code>join()</code>, as shown above.</p>

<p>The following example shows how.  First, we include the correct Boost thread header, create the thread object and pass in our worker function.  The main thread in the process will then wait for the thread to complete.</p>

<p><textarea name="code" class="c++" cols="60" rows="7">
    #include <iostream>
    #include <boost/thread.hpp>
    #include <boost/date_time.hpp>
    &nbsp;
    void workerFunc()
    {
        boost::posix_time::seconds workTime(3);
        &nbsp;
        std::cout &lt;&lt; "Worker: running" &lt;&lt; std::endl;
        &nbsp;
        // Pretend to do something useful...
        boost::this_thread::sleep(workTime);
        &nbsp;
        std::cout &lt;&lt; "Worker: finished" &lt;&lt; std::endl;
    }
    &nbsp;
    int main(int argc, char* argv[])
    {
        std::cout &lt;&lt; "main: startup" &lt;&lt; std::endl;
        &nbsp;
        boost::thread workerThread(workerFunc);
        &nbsp;
        std::cout &lt;&lt; "main: waiting for thread" &lt;&lt; std::endl;
        &nbsp;
        workerThread.join();
        &nbsp;
        std::cout &lt;&lt; "main: done" &lt;&lt; std::endl;
        &nbsp;
        return 0;
    }
</textarea></p>

<p>When you run the program, you should see output similar to the following:</p>

<pre><code>% ./t1
main: startup
main: waiting for thread
Worker: running
Worker: finished
main: done
</code></pre>

<p>It's as simple as that!  This created a thread and ran it, and you would have seen a pause while the worker thread was running (ok, busy sleeping!).  Later on, we'll do something a bit more substantial.  But this example shows the absolute minimum code required to start a simple thread.  Simply pass your function to the <code>boost::thread</code> constructor.</p>

<h2>Type 2: Function with Arguments</h2>

<p>So the above function wasn't terribly useful by itself.  We really want to be able to pass in arguments to the thread function.  And fortunately, it's very easy - you simply add parameters to the thread object's constructor, and those arguments are automagically bound and passed in to the thread function.</p>

<p>Let's say your thread function had the following signature:</p>

<p><textarea name="code" class="c++" cols="60" rows="1">
    void workerFunc(const char* msg, unsigned delaySecs) //...
</textarea></p>

<p>You simply pass the arguments to the thread constructor after the name of the thread function, thus:</p>

<p><textarea name="code" class="c++" cols="60" rows="1">
    boost::thread workerThread(workerFunc, "Hello, boost!", 3);
</textarea></p>

<p>This example is called 't2' in the source examples.</p>

<h2>Type 3: Functor</h2>

<p>A functor is a fancy name for an object that can be called just like a function.  The class defines a special method by overloading the <code>operator()</code> which will be invoked when the functor is called.  In this way, the functor can encapsulate the thread's context and still behave like a thread function.  (Functors are not specific to threads, they are simply very convenient.)</p>

<p>This is what our functor looks like:</p>

<p><textarea name="code" class="c++" cols="60" rows="37">
    class Worker
    {
    public: 
        &nbsp;
        Worker(unsigned N, float guess, unsigned iter) 
                : m_Number(N),
                  m_Guess(guess),
                  m_Iterations(iter)
        {
        }
        &nbsp;
        void operator()()
        {
            std::cout &lt;&lt; "Worker: calculating sqrt(" &lt;&lt; m_Number
                      &lt;&lt; "), itertations = "
                      &lt;&lt; m_Iterations &lt;&lt; std::endl;
            &nbsp;
            // Use Newton's Method
            float   x;
            float   x_last = m_Guess;
            &nbsp;
            for (unsigned i=0; i &lt; m_Iterations; i++)
            {
                x = x_last - (x_last*x_last-m_Number)/
                        (2*x_last);
                x_last = x;
                &nbsp;
                std::cout &lt;&lt; "Iter " &lt;&lt; i &lt;&lt; " = "
                      &lt;&lt; x &lt;&lt; std::endl;
            }
            &nbsp;
            std::cout &lt;&lt; "Worker: Answer = " &lt;&lt; x &lt;&lt; std::endl;
        }
    &nbsp;
    private:
    &nbsp;
        unsigned    m_Number;
        float       m_Guess;
        unsigned    m_Iterations;
    };
</textarea></p>

<p>This worker functor calculates a square root of a number using <a href="http://en.wikipedia.org/wiki/Newton%27s_method">Newton-Rhapson's method</a>, just for fun (ok, I got bored putting sleep in all the threads).  The number, a rough guess and the number of iterations is passed to the constructor.  The calculation (which is in fact extremely fast) is performed in the thread itself, when the <code>operator()()</code> gets called.</p>

<p>So in the main code, first we create our callable object, constructing it with any necessary arguments as normal.  Then you pass the instance to the <code>boost::thread</code> constructor, which will invoke the <code>operator()()</code> method on your functor.  This becomes the new thread, and runs just like any other thread, with the added benefit that it has access to the object's context and other methods.  This approach has the benefit of wrapping up a thread into a convenient bundle.</p>

<p><textarea name="code" class="c++" cols="60" rows="15">
    int main(int argc, char* argv[])
    {
        std::cout &lt;&lt; "main: startup" &lt;&lt; std::endl;
        &nbsp;
        Worker w(612, 10, 5);
        boost::thread workerThread(w);
        &nbsp;
        std::cout &lt;&lt; "main: waiting for thread" &lt;&lt; std::endl;
        &nbsp;
        workerThread.join();
        &nbsp;
        std::cout &lt;&lt; "main: done" &lt;&lt; std::endl;
        &nbsp;
        return 0;
    }
</textarea></p>

<p>Note: A very important consideration when using functors with boost threads is that the thread constructor takes the functor parameter <em>by value</em>, and thus makes a <em>copy</em> of the functor object.  Depending on the design of your functor object, this may have unintended side-effects.  Take care when writing functor objects to ensure that they can be safely copied.</p>

<h2>Type 4: Object method I</h2>

<p>It is frequently convenient to define an object with an instance method that runs on its own thread.  After all, we're coding C++ here, not C!  With Boost's <code>thread</code> object, this only slightly more work than making a regular function into a thread.  First, we have to specify the method using its class qualifier, as you would expect, and we use the <code>&amp;</code> operator to pass the address of the method.</p>

<p>Because methods in C++ always have an implicit <code>this</code> pointer passed in as the first parameter, we need to make sure we call the object's method using the same convention.  So we will pass the object pointer (or <code>this</code> depending on whether we are inside the object or not) as the first parameter, along with any other actual parameters we might have after that, thus:</p>

<p><textarea name="code" class="c++" cols="60" rows="2">
    Worker w(3);
    boost::thread workerThread(&amp;Worker::processQueue, &amp;w, 2);
</textarea></p>

<p>As an aside, take care in your own code that you don't accidentally allocate an object on the stack in one place, spawn a thread, then have the object go out of scope and be destroyed before the thread has completed!  This could be the source of many tricky bugs.</p>

<p>The full listing is essentially the same.  To pass additional parameters to the method, simply add them in the constructor to the thread object after the object pointer.</p>

<h2>Type 5: Object method II</h2>

<p>You may want to create a bunch of objects that manage their own threads, and can be created and run in a more flexible manner than keeping around a bunch of objects along with their associated threads in the caller.  (I think they call this encapsulation.)</p>

<p>So our final example places the thread instance within the object itself, and provides methods to manage them.  Since the thread object exists as an instance member (as opposed to a pointer), what happens in the constructor?  In particular, what if we don't want to run the thread at the same time as we create our object?  Fortunately, the default constructor for the thread creates it in an "invalid" state, called <code>not-a-thread</code>, which will do nothing until you assign a real one to it (in our <code>start</code> method, for example).</p>

<p>So now our class declaration has the following data member added:</p>

<p><textarea name="code" class="c++" cols="60" rows="4">
    //...
    private:
        boost::thread    m_Thread;
    //...
</textarea></p>

<p>The <code>Worker::start()</code> method spawns the thread which will run the <code>processQueue</code> method.  Notice how we pass in <code>this</code> as the first bound parameter?  Because we are using an instance method (and not a class method or regular function), we must ensure the first parameter is the instance pointer.  The <code>N</code> parameter is the first actual parameter for the thread function, as can be seen in its signature.</p>

<p><textarea name="code" class="c++" cols="60" rows="4">
    void start(int N)
    {
        m_Thread = boost::thread(&amp;Worker::processQueue, this, N);
    }
</textarea></p>

<p>The join method is very simply:</p>

<p><textarea name="code" class="c++" cols="60" rows="3">
    void join()
    {
        m_Thread.join();
    }
</textarea></p>

<p>which means our main function becomes no more than:</p>

<p><textarea name="code" class="c++" cols="60" rows="3">
    Worker worker;
    &nbsp;
    worker.start(3);
    &nbsp;
    worker.join();
</textarea></p>

<p>This encapsulation of the threading can be very useful, especially when combined with patterns such as the Singleton (which we will look at in a future article).</p>

<h2>Conclusion</h2>

<p>We have seen a variety of techniques for creating threads using the Boost threading library.  From simple C functions to instance methods with parameters, the thread class permits a great deal of flexibility in how you structure your application.</p>

<h2>Future Articles</h2>

<p>In later installments, we will look at synchronisation methods, mutexes, and all sorts of other interesting techniques.</p>

<p>Please leave a comment below, with any questions or feedback you may have.  Too long?  Too brief?  More details required?  Something confusing?  Let me know.</p>
]]>
    </content>
</entry>

<entry>
    <title>Paying twice?</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2009/05/paying-twice.html" />
    <id>tag:antonym.org,2009://1.156</id>

    <published>2009-05-02T13:11:08Z</published>
    <updated>2009-05-02T13:11:10Z</updated>

    <summary>When you buy a car, you get a warranty, these days typically for 3 years on a decent model. Provided you keep up the fluid levels and do a bit of scheduled preventative maintenance, you&apos;re covered. So if the car...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        When you buy a car, you get a warranty, these days typically for 3 years on a decent model.  Provided you keep up the fluid levels and do a bit of scheduled preventative maintenance, you&apos;re covered.  So if the car fails, something breaks, or generally doesn&apos;t work the way it should, the supplier will fix it - for free.  After all, you&apos;ve paid for the car, you have a reasonable expectation of performance, safety and reliability.  And ensuring that happens is good customer service and good business.

So why isn&apos;t the same applied to computers and software?

(This is an old rant I never quite finished, and decided to publish now just for fun - and see if it sparks any reaction.)

        <![CDATA[Hypothetically speaking, would you be prepared to pay Ford an annual fee - on top of the purchase price - to help prevent the wheels from falling off due to dodgy wheel nuts they decided to use to save a few bucks?  If not, why would you buy <a href="http://www.windowsonecare.com/Default.aspx">Microsoft's OneCare</a> package?

Microsoft charges a RRP of US$49.95 for its new OneCare package.  And so what do you get?

<ul><li>Anti-virus</li>
<li>Anti-spyware</li>
<li>System Firewall</li>
<li>System Backup</li>
<li>Performance 
<li>Software Updates</li></ul>

But aren't many of these "extras" simply products that fix or mitigate against defects and flaws in the original system?

<h3>Anti-virus and Anti-spyware</h3>

Microsoft practically invented the US$4 Billion per annum market for antivirus software.  The likes of Symantec, Norton and Computer Associates seem to exist almost by virtue of design flaws in the Windows operating system and its applications - the most common targets being Microsoft Office and Internet Explorer.

The equation is simple: if there is a security flaw, it will eventually be found and exploited.  Eliminate the flaws, and there will be no exploits.  No exploits means we won't be losing billions more dollars per year.

Obviously the more complex an application, the more potential there is for security issues to arise.  And developing exploit-free software is incredibly difficult.  But how many times have we heard over the years that Microsoft is stopping work on new functionality and focusing purely on security?  How has that really worked out for us?  Would people prefer less features and more security, or the other way around?

<h2>It's Plus and its Live</h2>

What does this all really mean?  It's called <b>Plus</b> because you're paying extra for it.  And it's <b>Live</b> because it's on this new-fangled Internet thingy.  Yes, these marketing folk are worth every penny.  (Especially when they count some features more than once, to "flesh out" the feature set.)

<h3>Protection Plus</h3>

<li><b>Virus Scan</b>: you paid for an insecure operating system, now you have to pay for the cure - but not the prevention.  It's like the morning-after pill for your computer, but without the warm fuzziness.</li>
<li><b>Anti-Spyware</b>: not only are Windows and Office so riddled with security flaws that you need all this technology to protect you, but Internet Explorer can invisibly infect your PC with software that steals your credit card details and sends it to the Russian mafia, all with a single click.</li>
<li><b>Software Updates</b>: but you already get this built in with (the incredibly annoying) Windows Update.  Is there really a <i>genuine advantage</i> to this <b>Plus</b> feature??</li></ul>

<h3>Performance Plus</h3>

<li><b>Defragments your hard disk</b>: but wasn't NTFS (New Technology filesystem) was supposed to free us from the dim dark ages of FAT and defragging?</li>
<ul><li><b>Anti-Virus</b>: wait, they already counted this one under 'Protection'.  But it improves the 'performance' too?  Fluff!</li>
<li><b>Free up hard disk space</b>: this is almost laughable - go read the website for yourself, I'm not making this up: it deletes useless junk files in your temporary directory.</li>
<li><b>Software Updates</b>: this was also listed under 'Protection'.</li>
<li><b>Semi-automatic backups</b>: this is useful, but I daresay there are better products out there that just do backup, and do it <b>well</b>.</li>
</ul>

This little gem in the product features list just stood out:

<blockquote>If a file on your computer is trying to do something that is unusual for that file type—a picture file trying to create a connection to the Internet, for example—Windows Live OneCare can catch that behavior and block the file.</blockquote>

Why isn't anyone asking: "what the hell kind of system are we running when a picture file can create a connection to the internet?"

<h2>Caveat Emptor</h2>

Are consumers really that ignorant that they believe this is an acceptable situation?  Do they not hold Microsoft accountable for at least some of the problems they routinely experience?  They are lucky the EULA (End-User License Agreement) basically disclaims Microsoft of almost any responsibility whatsoever, regardless of whether or not it was their poor design that caused the problem or enabled it to happen.

In terms of the other incumbents, you can bet that Symantec isn't happy about Microsoft muscling in to their traditional market (wouldn't be the first time!).  I suppose what Microsoft giveth, they can also taketh away.

Gates had the temerity to blame all the crackers out there for the ongoing problems with Windows.  That's like blaming the driver for the crash when the wheels fall off.  Remember Bridgestone?

So how is it going?  Well apaprently it is <a href="http://news.com.com/Microsofts+antivirus+package+makes+a+splash/2100-7355_3-6104926.html?tag=newsmap">selling like hotcakes</a> - but who knows why?  Maybe people are sick of the spyware, the viruses, the slowdown, the constant invasion of your machine by malicious faceless outsiders.  And I guess that fear is what keeps good customers paying, in the hope that the <b>next</b> major release, service pack, or whatever will solve all their problems...  Surely?
]]>
    </content>
</entry>

<entry>
    <title>Use your brain!</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2009/05/use-your-brain.html" />
    <id>tag:antonym.org,2009://1.155</id>

    <published>2009-05-02T12:18:55Z</published>
    <updated>2009-05-02T12:18:57Z</updated>

    <summary>When I was in high school, I got a new calculator - my first scientific calculator. It wasn&apos;t one of those fancy graphing calculators, nor was it programmable. But it did have lots of buttons and functions, and it was...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>When I was in high school, I got a new calculator - my first scientific calculator.  It wasn't one of those fancy graphing calculators, nor was it programmable.  But it did have lots of buttons and functions, and it was shiny.  Excited by my new toy, I would use it for all sorts of things.  I could evaluate complex equations in a flash!  It was great!  So, I started using it for everything, even for simple calculations that I used to "waste time" doing in my head.  No more would I leave an answer in its boring 3π/2 form - I would evaluate it to 9 decimal places!</p>
]]>
        <![CDATA[<p>Before long, I was using the calculator to evaluate trivial things like 7-9, just "to be sure" it was really -2.  And gradually, the calculating part of my brain started to atrophy.  I relied on my calculator for everything, so my brain didn't need to think or calculate, just remember.  I had no idea at the time, but my numeracy skills were slipping badly.</p>

<p>It took quite some time before I realised I was relying on this number-crunching "crutch" far too much, and I didn't like it one bit.  So one day, I decided to leave my calculator at home.  I forced myself to calculate everything in my head, doing long division where necessary, writing out the expansions of a large multiplication, and leaving answers as vulgar fractions.</p>

<p>It was slow at first, but eventually my calculation muscles got the workout they needed, and I became quite fast.  It took some effort, but it was worth it.  I still used my calculator occasionally, but I relied on my built-in one most of the time.  Eventually my calculating muscles came back, and I was all the better for it.</p>

<p>Oh, and it's probably worth pointing out that an answer of 3π/2 is actually more accurate than evaluating a decimal approximation - even if you do have 9 decimal places!</p>
]]>
    </content>
</entry>

<entry>
    <title>The first user</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2009/04/the-first-user.html" />
    <id>tag:antonym.org,2009://1.154</id>

    <published>2009-04-30T12:26:08Z</published>
    <updated>2009-04-30T12:29:01Z</updated>

    <summary>When you are developing a new piece of software, you typically first spend quite some time setting up your development environment. As you progress, your application becomes a very cozy inhabitant of this environment, a safe happy cocoon that has...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>When you are developing a new piece of software, you typically first spend quite some time setting up your development environment.  As you progress, your application becomes a very cozy inhabitant of this environment, a safe happy cocoon that has evolved as you make lots of small changes to the application or your system.  What could possibly go wrong?</p>
]]>
        <![CDATA[<p>Eventually you will have something to actually test, and the time comes to send your little application out into the "Real World", to be tested in the some unknown, potentially harsh environment for which it may be ill prepared.</p>

<p>Your first user comes along when you run your software on any machine other than the one it was created on.  Getting your application to run on another machine is a very important milestone in the overall lifecycle, and doing it earlier rather than later can help flush out all sorts of potential problems.  (Getting it to build on another machine is a topic for another day.)</p>

<p>So what sort of issues do you need to consider?</p>

<h2>System Requirements</h2>

<p>What kind of hardware requirements does it have?  Does it test for system requirements on startup?  Does it produce sensible diagnostic messages if anything is lacking?  What is the working set (typical memory usage) or your application?  Can you estimate memory requirements?  What disk space, beyond the installed files, does it require?  Is it performance-sensitive, and if so, have you profiled it to determine what baseline CPU is required?  Do you require any particular drivers to be present?</p>

<h2>Packaging and Dependencies</h2>

<p>Do you need an installer program?  Can it run standalone, from a network drive, or a USB stick? What are the runtime dependencies?  In other words, which shared libraries or DLLs does it need to run?  Do you need to provide the redistributable C or C++ runtime?  What resources does it need (ie. images, sounds, help files, shaders, scripts, etc)?  What configuration settings does it require?  Does it have sensible defaults for any preferences that aren't set in a fresh installation?  Does it use optional features that are only available in a certain version of the OS?  Does it assume that particular files are to be found in a particular directory?  The current directory?  The same directory as the executable?  Any assumptions you make during development will surely be tested.  Just getting the application to launch, let alone run correctly, is the first hurdle.</p>

<h2>Logging</h2>

<p>You will most likely be providing a Release build to external users.  However, this typically disables any debug logging you might have placed in your code.  If anything should go wrong (against all odds!), you will really save time if you can leave logging on in a Release build, so you can get your guinea pigs to email you the output in the event of the unthinkable.</p>

<h2>Versioning</h2>

<p>Give each release a unique and easily identifiable version number.  Show it in the About box, or even in the title bar.  Embed it in the resource metadata of the executable.  Make it easy to answer the question "which version is <em>that</em> you're running?"  If it is supported, you can even add it as a suffix of the executable filename, so you can have multiple versions in the one directory, which can be quite handy.</p>

<h2>Release Notes</h2>

<p>Make sure you describe what features work, what features are missing, and what changed in the most recent release.  Don't forget to describe known bugs, too.  Otherwise you will be peppered with "well X doesn't work!" comments, when you know already, you're just not up to that bit yet!  Also provide at least a date and version number, which can be correlated with the software.  Any bugs that get filed will obviously require this information, and it helps with tagging in your version control system too.</p>

<h2>And more...</h2>

<p>As I was writing the above, it became clear that each one of these topics could become an article on its own.  Please comment below if you would like to see more detailed discussion on the above, or have some thoughts to share on the topic.</p>
]]>
    </content>
</entry>

<entry>
    <title>Improve your C++: const-correctness</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/11/improve-your-c-const-correctness.html" />
    <id>tag:antonym.org,2008://1.152</id>

    <published>2008-11-22T03:18:14Z</published>
    <updated>2008-11-22T12:51:57Z</updated>

    <summary>Writing &#8220;const-correct&#8221; code will improve the quality and maintainability of your code. It is especially important and useful when writing Object-Oriented code, as objects are often passed around as constant references. Properly declaring non-mutating methods as const allows you to...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
        <category term="C++ Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="c++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="dev" label="dev" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>Writing &#8220;const-correct&#8221; code will improve the quality and maintainability of your code.  It is especially important and useful when writing Object-Oriented code, as objects are often passed around as constant references.  Properly declaring non-mutating methods as <code>const</code> allows you to safely call any <code>const</code> method on such a reference.  It is part of good type-safe practice and good code hygiene. So how do we do it?</p>
]]>
        <![CDATA[<h2>Definitions</h2>

<p>First, some definitions.</p>

<ul>
<li><em>mutating</em>: any function or method that alters the state of an object (ie. makes an assignment to any of its data members) is a &#8216;mutating&#8217; operation. For example, calling a &#8220;setter&#8221; method is a mutating operation.</li>
<li><em>non-mutating</em>: any operation that does not modify the object&#8217;s data members.  For example, calling a &#8220;getter&#8221; method.</li>
<li><code>const</code> <em>parameter</em>: if you have a constant reference or pointer to an object, you may not modify it or call any mutating methods on it.</li>
<li><code>const</code> <em>method</em>: a method declared constant, promises not to modify the object when called.</li>
<li><code>const</code> <em>correct</em>: writing code that consistently declares methods and parameters <code>const</code>, wherever possible</li>
</ul>

<p>There are two simple rules of thumb to follow:</p>

<ol>
<li>If a method does not modify the object&#8217;s state, the method should be declared <code>const</code></li>
<li>If a method or function does not modify a pointer or reference parameter, the parameter should be declared <code>const</code></li>
</ol>

<p>Together, these two rules ensures that objects are <code>const</code> as often as possible.  Why is this a good thing?  It gives the compiler more type information, which can catch potential bugs, and even give opportunities for optimization.</p>

<p>How do you declare a method to be <code>const</code>?  Just add the <code>const</code> keyword after the normal method declaration, thus:</p>

<p><textarea name="code" class="c++" cols="60" rows="7">
class A
{
public:
    // &#8230;
    unsigned calculateSum() const;
    // &#8230;
};
</textarea></p>

<p>You declare a function or method parameter <code>const</code> in the usual way.  Note that in C++, references are usually preferred over pointers wherever possible (unless the parameter could be <code>NULL</code>).</p>

<p><textarea name="code" class="c++" cols="60" rows="4">
unsigned processTree(const node&amp; root)
{
    // &#8230;
}
</textarea></p>

<h2>Less Good Example</h2>

<p>Let&#8217;s use a simple Customer class as an example.  This is valid, but not really const-correct code:</p>

<p><textarea name="code" class="c++" cols="60" rows="31">
class Customer
{
    public:
        Customer(std::string name) :
            _name(name)
        {
        }
        std::string getName()
        {
            return _name;
        }
       void setName(std::string aName)
        {
            _name = aName;
        }
        // &#8230;
    private:
        std::string _name;
        // &#8230;
};
&nbsp;
// &#8230;and elsewhere&#8230;
unsigned Invoice::addCustomer(Customer&amp; cust)
{
    // &#8230;call any methods
}
//
unsigned Invoice::getInvoiceCountFor(Customer&amp; cust)
{
    // &#8230;call any methods
}
</textarea></p>

<p>There are several opportunities here to add <code>const</code> qualifiers to the code.  The accessor method for <code>name</code> does not modify the object state, so it can be made into a <code>const</code> method by adding the keyword at the end of the method signature.  The initial value for <code>name</code> in the constructor, along with the new name in the mutator can both take <code>const</code> references to strings (instead of passing by-value, which is less efficient).</p>

<h2>Improved Example</h2>

<p>So the above code becomes:</p>

<p><textarea name="code" class="c++" cols="60" rows="31">
class Customer
{
    public:
        Customer(const std::string&amp; name) :
            _name(name)
        {
        }
        std::string getName() const
        {
            return _name;
        }
       void setName(const std::string&amp; aName)
        {
            _name = aName;
        }
        // &#8230;
    private:
        std::string _name;
        // &#8230;
};
&nbsp;
// &#8230;and elsewhere&#8230;
unsigned Invoice::addCustomer(const Customer&amp; cust)
{
    // &#8230;call any const methods
}
//
unsigned Invoice::getInvoiceCountFor(const Customer&amp; cust)
{
    // &#8230;call any const methods
}
</textarea></p>

<p>Once you have a <code>const</code> reference to an object (such as the <code>cust</code> parameter above in <code>getInvoiceCountFor()</code>, you can only call <code>const</code> methods on that object.  For example, the compiler will flag it as an error if you try to call <code>setName()</code>, as it is a mutating method.</p>

<h1>Advantages</h1>

<p>So why go to the extra effort?  Doesn&#8217;t it mean you can do <em>less</em> with the objects if you go around declaring things <code>const</code>?  Potentially, yes.  But there are a number of benefits:</p>

<ul>
<li>giving the compiler more type information can help catch potential bugs</li>
<li>establishes a &#8220;contract&#8221;, so you know that certain methods or functions will not modify your objects</li>
<li>acts as a form of documentation, by declaring the behaviour of methods and treatment of parameters</li>
<li>provides opportunities for optimization by the compiler</li>
</ul>

<h2>Summary</h2>

<p>By following the two simple rules above, you can write tighter, safer code that is easier to manage.</p>
]]>
    </content>
</entry>

<entry>
    <title>New blog setup</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/11/new-blog-setup.html" />
    <id>tag:antonym.org,2008://1.151</id>

    <published>2008-11-08T06:17:39Z</published>
    <updated>2008-11-08T06:17:51Z</updated>

    <summary>This blog is now powered by the wonderful MovableType, Open Source Edition, running on SliceHost. Installation was painless, following the instructions on the main website. I used PostgreSQL, my favourite RDBMS, on the back-end. I got a basic site up...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>This blog is now powered by the wonderful <a href="[http://www.movabletype.org/">MovableType, Open Source Edition</a>, running on <a href="http://www.slicehost.com/">SliceHost</a>.</p>

<p>Installation was painless, following the instructions on the main website.  I used <a href="http://www.postgresql.org/">PostgreSQL</a>, my favourite RDBMS, on the back-end.  I got a basic site up very quickly, and chose one of the supplied templates to get started.</p>
]]>
        <![CDATA[<h1>Migrating</h1>

<p>I migrated all the old content from my old <a href="http://www.drupal.org/">Drupal</a> installation, using an <a href="http://andrew.sterling.hanenkamp.com/2008/03/drupal-to-movable-type.html">export script</a> that saved the Drupal nodes and comments into a text file that MT imports directly.  I ended up using the Python version of the script posted by a commenter by the name of "Charles S", with a few modifications.  The main change I made was to add a status filter to the query to exclude spam comments (making up over 90% of the thousands of entries).</p>

<h1>Setup</h1>

<p>Once I imported all the old content, I had to tidy up a few things, but it went surprisingly well.  I added a few custom templates and widgets, which was a good learning experience to figure out how to customize things.  I'm impressed with how powerful and flexible it is.  I added a "badge" for Twitter updates, and another one for Flickr.</p>

<p>I tend to post a lot of source code snippets in the code I write, and I really need to publish nice-looking code with syntax-highlighting.  After much searching and reading, I settled on <a href="http://code.google.com/p/syntaxhighlighter/">SyntaxHighlighter</a>, which uses JavaScript to highlight code on the page.  You put the source in a textarea with a special ID, and it will dynamically transform the code when displayed.  It's very nice, and easy to install and use.</p>

<h1>Comments</h1>

<p>I had a huge problem with spam on the old blog, and Drupal's facilities for dealing with spam made it almost impossible to manage.  I haven't enabled anonymous comments here yet, but <a href="http://www.openid.org/">OpenID</a> is now supported in addition to a simple registration process.  I'm hoping that people will use OpenID for a low-friction way of posting comments.</p>

<p>Since all the major free email providers (Google, Yahoo and Microsoft) now support OpenID to some degree, I'm keen to see this gaining more traction.</p>

<h1>Posting</h1>

<p>The built-in web-based post editor in MT seems very powerful, and supports a WYSIWYG mode as well as various markup types.  It seems to provide all the features you'd want, though the edit/preview/edit cycle is a little slow.  While I do use the built-in editor, I tend to write when I have both ideas and time, which often does not coincide with having connectivity.</p>

<p>To solve this problem, I upgraded to the latest version of <a href="http://www.red-sweater.com/marsedit/">MarsEdit</a>, so I can write and edit posts while offline.  It's a great Mac-based blogging client, with some great new features, including Flickr support and image handling.</p>

<p>Rather than dynamically producing content like other CMS packages, MT generates static files for your blog entries and pages.  This has the advantage of being very fast and efficient, but to perform the "publish" stage of generating the static output can sometimes take a while (depending on various factors).  Still, I think the pros outweigh the cons, and it's a very slick package.</p>

<h1>Categories and Tagging</h1>

<p>I had only used basic tagging before, and MT adds categories and keywords, which is nice and flexible but requires some thought for a sensible ontology.  It will take a while to figure out a good structure for the content to come, but I now see I have many ways or organising the content.</p>

<h1>Ahead</h1>

<p>MT has the combination of a powerful blogging platform, and the ability to publish static pages and other assets, and thus addresses nearly all my needs.  I'll probably end up using <a href="http://trac.edgewall.org/">Trac</a> for publishing code for some of the projects I'm working on.</p>

<p>If anyone is interested in any more detail about the MovableType setup, drop me a note in the comments.  I'd especially like to hear from someone commenting using OpenId.</p>
]]>
    </content>
</entry>

<entry>
    <title>Taking it for granted</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/10/taking-it-for-granted.html" />
    <id>tag:antonym.org,2008://1.2</id>

    <published>2008-10-28T12:48:36Z</published>
    <updated>2008-10-28T12:54:31Z</updated>

    <summary>I fell into the trap of thinking that every blog entry had to be fascinating, amazing, new, whiter, brighter and generally earth-shattering. But curiously I often read very popular blogs where people write about topics or techniques that I would...</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    <category term="meta" label="meta" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[I fell into the trap of thinking that every blog entry had to be fascinating, amazing, new, whiter, brighter and generally earth-shattering. But curiously I often read very popular blogs where people write about topics or techniques that I would consider obvious. And then one day it struck me - I was taking a great deal for granted.<div><br /></div><div>So I decided I will start writing more articles (short ones that make it to publishable stage!) about some of these things. It will almost certainly be about software development, but not strictly so. Who knows what tangent I might strike out on...?</div><div><br /></div><div>It will also give me a chance to exercise this new blog. Hopefully Google will actually start indexing it properly now.</div>]]>
        
    </content>
</entry>

<entry>
    <title>Opening the floodgates</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/06/opening-the-floodgates.html" />
    <id>tag:antonym.org,2008://1.147</id>

    <published>2008-06-02T05:38:28Z</published>
    <updated>2008-10-30T01:07:45Z</updated>

    <summary>In order to potentially double the readership of this blog from 2 to 4 people (Hi, Mom!) I&apos;ve registered with Technorati, to see how that helps people find my site.  You can visit my Technorati Profile and see for yourself.  Note that there&apos;s only 1.1 Million blogs in my path as I skyrocket to the top!</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>In order to potentially double the readership of this blog from 2 to 4 people (Hi, Mom!) I've registered with Technorati, to see how that helps people find my site.  You can visit my <a href="http://technorati.com/people/technorati/gavinb" rel="me">Technorati Profile</a> and see for yourself.  Note that there's only 1.1 Million blogs in my path as I skyrocket to the top!</p>]]>
        
    </content>
</entry>

<entry>
    <title>Coupling: Bill and Steve</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/05/coupling-bill-and-steve.html" />
    <id>tag:antonym.org,2008://1.146</id>

    <published>2008-05-30T01:13:43Z</published>
    <updated>2008-11-01T12:26:07Z</updated>

    <summary>Long ago, I was pointed to a most insightful post about coding culture at Microsoft (Bill&apos;s company) compared with Apple (Steve&apos;s company).  They observed that at Microsoft, there is a tendency is to use trees as the preferred data structure.  Trees are certainly convenient and appropriate for many underlying representations, and are generally easy to manipulate.  At Apple, on the other hand, there is a tendency to use hash tables.</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    <category term="industry" label="industry" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="software" label="software" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>Long ago, I was pointed to a most insightful <a href="http://weblog.scifihifi.com/2004/12/25/data-structures-as-culture/">post about coding culture</a> at Microsoft (Bill's company) compared with Apple (Steve's company).  They observed that at Microsoft, there is a <i>tendency</i> is to use <a href="http://en.wikipedia.org/wiki/Tree_%28data_structure%29">trees</a> as the preferred data structure.  Trees are certainly convenient and appropriate for many underlying representations, and are generally easy to manipulate.  At Apple, on the other hand, there is a <i>tendency</i> to use <a href="http://en.wikipedia.org/wiki/Hash_table">hash tables</a>.</p>

<p>Trees tend to impose a hierarchy, enforcing a one-to-many structure (regardless of natural relationships).  Hash tables are a looser form of association, which don't necessarily impose structure.  This distinction tends to reflect a subtle but significant difference in the underlying philosophy and approach to problem solving and architecture.</p>
]]>
        <![CDATA[<p>And what I've noticed, at several levels, is there is another fundamental difference in thought patterns between the two companies, especially when it comes to <b>coupling</b>.  <a href="http://en.wikipedia.org/wiki/Coupling_%28computer_science%29">Coupling</a> is (in Software Engineering terms, not the brilliant <a href="http://www.bbc.co.uk/comedy/coupling">BBC comedy</a>) the level of knowledge one component has of another, a measure of dependence.  Highly coupled code is fragile and difficult to maintain, in that changes in one module may necessitate changes in the dependent module.  Loosely coupled code is supposed to rely only on public interfaces, is abstracted from the implementation by its interface, and is more maintainable and resilient to change.</p>

<p><strong>Bill's House</strong></p>

<p>Microsoft often tends to go for <i>tight coupling</i>.  This is evident from the code at the low levels, to their architecture at the high levels, to the protocols that connect components.  Certainly, at the product level there is no doubting that Microsoft go out of their way to <b>integrate</b> (a synonym for a certain type of coupling) their products, horizontally and vertically.  For example: Outlook is tightly coupled to Exchange.  Thre are many features that are only available to users of either product when used together.  This necessarily implies that they have a significant degree of knowledge about each other.</p>

<p>This was illustrated in a striking way in a <a href="http://blogs.msdn.com/philipsu/archive/2006/06/14/631438.aspx">posting by a senior Microsoft employee</a> involved with Windows development, who very candidly highlights some of the many problems plaguing Vista and delaying its release:</p>

<blockquote>Windows code is too complicated.  It's not the components themselves, it's their interdependencies.  <u>An architectural diagram of Windows would suggest there are more than 50 dependency layers</u> (never mind that there also exist circular dependencies).  After working in Windows for five years, you understand only, say, two of them.  Add to this the fact that building Windows on a dual-proc dev box takes nearly 24 hours, and you'll be slow enough to drive Miss Daisy.</blockquote>

<p>If you look at the Windows API level, down at the code: there are countless examples of where one object relies on the particularities of another.  (Note: This is based on my past prorgamming experience with the Win32 C API and MFC, the thin wrapper around it.  I have no experience with .NET, so cannot comment on that.  I do note however that many experts have complained about architectural shortcomings of .NET v1.)</p>

<p>Microsoft's tendency for coupling is also often used strategically, as leverage to keep control of the platform, or to keep competitors out of a market.  There are several high-profile examples of this, such as the recent <a href="http://www.groklaw.net/article.php?story=20070923170905803">EU antitrust case</a>.</p>

<p><strong>Steve's House</strong></p>

<p>Apple on the other hand <i>tends</i> to go for loose coupling.  They frequently embrace open protocols and standards, which inherently promotes loose coupling.  The Mac OS X architecture features many examples of loose coupling.  Apple tends to make up for the lack of integration of disparate packages by providing "glue", typically user-friendly front-ends to frequently complex back-end systems.  They're not perfect, they do have plenty of proprietary software products, but they use open systems where it makes sense.</p>

<p>At the API level, even at the object level, interfaces and protocols (the Objective-C kind) keep the lowest levels decoupled.  I have not seen a more flexible GUI framework than Cocoa (and I have used many), and it is largely due to its elegant design and decoupled nature.  It is incredibly easy to customize the behaviour of the interface widgets, because the interface is decoupled from the implementation.</p>

<p>People often complain that Apple use underhanded strategies to keep control of the iTunes/iPod market.  But take a look: the audio codec used is <a href="http://en.wikipedia.org/wiki/AAC">AAC</a> (Advanced Audio Codec, an ISO standard), the file format is MPEG-4 (another ISO standard, not coincidentally based on Apple's own QuickTime).  The video format used is <a href="http://en.wikipedia.org/wiki/MPEG-4">H.264</a> (MPEG-4 Part 10, a standard).  The DRM is only there at the insistence of the paranoiacs in the Recording Industry, and as Steve points out, he'd rather do away with it (and in fact has for many labels now, such as EMI).  Now there is certainly tight coupling between the iPod, iTunes and the iTunes Store, as the entire experience is designed to be streamlined.  But you don't have to use the store to use an iPod, and vice versa - it's simply easier that way.</p>

<p>An obvious criticism to this argument is that Mac apps are coupled to the Mac platform (operating system and hardware).  While patently obvious and correct, Windows apps are similarly coupled to the operating system - you just get to choose which hardware you run it on.  The cost of that flexibility is paid in driver compatibility issues, integration problems, flaky system support, and so on.  It's a trade-off that many are happy to make.  In any case, I'm more interested in coupling at the application and protocol level.</p>

<p>Steve seems to be quite content to cater to the upper end of the market, rather than taking over every space in every market.  Being smaller, Apple simply doesn't have the weight to throw around and force people to use their products, so in some ways they have to be more flexible (viz the Exchange support in Mail.app, or Active Directory support in Leopard Server for example).  So to survive, Steve has to ensure (at least to some extent) that the products are not too tightly coupled together.</p>

<p><strong>My Dream Home</strong></p>

<p>I'd like to build a software house, one that embraces standards, empowers customers, and uses creativity and clever design to gain market share, not patents.  And of course, I'll always try to keep my code nicely decoupled - and use hash tables <b>and</b> trees where appropriate!</p>
]]>
    </content>
</entry>

<entry>
    <title>Feet to the fire...</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/05/feet-to-the-fire.html" />
    <id>tag:antonym.org,2008://1.145</id>

    <published>2008-05-30T00:48:14Z</published>
    <updated>2008-11-01T12:37:15Z</updated>

    <summary>No, I&apos;m not talking about lazy Winter evenings on a rug...  I&apos;m talking about the responsibility of journalists to investigate, analyse, ask difficult questions, and cut through the hype and hyperbole.

So when a Senior Editor of eWeek sits down with a Microsoft SVP to discuss the recent deal with Novell, you would expect some thorough Q&amp;A on this highly significant development.  Instead, you get what reads like softball questions and slick pre-prepared answers.</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        <![CDATA[<p>No, I'm not talking about lazy Winter evenings on a rug...  I'm talking about the responsibility of journalists to investigate, analyse, ask difficult questions, and cut through the hype and hyperbole.</p>

<p>So when a Senior Editor of eWeek sits down with a Microsoft SVP to <a href="http://www.eweek.com/article2/0,1895,2060750,00.asp">discuss the recent deal with Novell</a>, you would expect some thorough Q&A on this highly significant development.  Instead, you get what reads like softball questions and slick pre-prepared answers.</p>]]>
        <![CDATA[<p>Look at this example: when asked a general question about the deal, Muglia replies:</p>

<blockquote>
"...this is the answer to questions customers have had about the assurance that they are in compliance with intellectual property rules with Linux. [...] So this deal is a milestone in that it shows how commercial and open-source companies can work together to assure customers that when they acquire Novell SUSE's open-source technology they are in compliance with, and are respecting, all of the intellectual property that exists in the environment."
</blockquote>

<p>You get the usual marketing-speak that we've come to expect from Microsoft.  Now there's some loaded statements in there, which just beg further scrutiny.  But rather than dig deper, probe, analyse, scrutinise - we get another bland question. Remember, this is a "sit down" meeting (as declared in the leading paragraph), so Galli presumably had every opportunity to expand the discussion.</p>

<p>Some possible follow-up questions:</p>

<ul><li>How many of your customers are asking for assurance?  What are they worried about?</li>
<li>What are you referring to when you mention "intellectual property"? Surely you are just talking about Patents?  If so, which patents are you claiming are infringing?</li>
<li>Linux distributions are typically comprised of hundreds or even thousands of components, so what in particular are you referring to here?  Are you focusing Samba and Mono (for example)?  Are there other components implicated?</li>
<li>What sort of analysis have you done on the Linux codebase to identify these potentially infringing code?</li>
<li>You seem to be implying Linux is infringing on Microsoft patents.  Which patents have you identified?  What steps have you taken to resolve these potential infringements with the Linux developers?</li>
<li>How do you see Linux as not respecting "intellectual property"?</li>
<li>When you say "environment", are you referring to patents other than those in Microsoft's portfolio?  Are you aware of other companies with possible patent claims?</li>
<li>Is the timing of this announcement coincidental, just as the SCO case (where SCO accused IBM of "dumping" their "IP" into Linux) is on its last dying breath?</li>
</ul>

<p>(And those are just the questions I have time to type up while reading that single paragraph on the train.  I've got some great questions for Novell too...)</p>

<p>Unfortunately I see this style of article all over the trade press.  There seems to be precious few journalists who see their it as duty to dig beyond the stock answers.  Whatever happened to the followup?  Instead, they seem to be perfectly content with getting canned responses to their answers and publishing something that seems more like a thinly velied press release than real news or investigation.  The result is not much more than providing a marketing platform for the interviewer.  You would expect more from a Senior Editor, would you not?</p>]]>
    </content>
</entry>

<entry>
    <title>iPhone musings</title>
    <link rel="alternate" type="text/html" href="http://antonym.org/2008/05/iphone-musings.html" />
    <id>tag:antonym.org,2008://1.144</id>

    <published>2008-05-30T00:43:12Z</published>
    <updated>2008-11-01T12:49:14Z</updated>

    <summary>It&apos;s amazing how many articles about the iPhone have been produced online and in print over the last year or so, dedicated to covering the minutiae of Apple&apos;s big splash.  Frankly, not owning one, I&apos;m getting a little tired of seeing articles about it everywhere I look.  So, I figure if you can&apos;t beat them, join them - and if every single other blog can have an opinion on the iPhone, so can I.  (This was actually written a few months ago, and I cleaned it up for publication in an attempt to catch up on my backlog of half-written articles.)</summary>
    <author>
        <name>Gavin Baker</name>
        
    </author>
    
    <category term="industry" label="industry" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mac" label="mac" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://antonym.org/">
        It&apos;s amazing how many articles about the iPhone have been produced online and in print over the last year or so, dedicated to covering the minutiae of Apple&apos;s big splash.  Frankly, not owning one, I&apos;m getting a little tired of seeing articles about it everywhere I look.  So, I figure if you can&apos;t beat them, join them - and if every single other blog can have an opinion on the iPhone, so can I.  (This was actually written a few months ago, and I cleaned it up for publication in an attempt to catch up on my backlog of half-written articles.)
        <![CDATA[<h2>Pricing</h2>

<p>Early adopters flocked in droves to Apple and AT&amp;T stores to be the first kid on the block to buy a new iPhone.  And by all accounts, they are overwhelmingly happy with their new purchase.  They decided it was worth the purchase price, and chose to spend their money on what appears to be an amazing piece of tech.  And by and large, the iPhone has (unlike so many that have gone before it) lived up to the hype.</p>

<p>Then a few months after the launch, Apple have decided to lover the price, making it an even more attractive to the next wave of consumers.  If ever there was any doubt, the lower price will likely create a second wave of purchases.</p>

<p>It must be acknowledged that Apple faced a great deal of risk and uncertainty in launching their first ever product into the cut-throat mobile market.  And the high launch price reflects to some degree the risk involved in their gambit.  If they didn't reach their minimum break-even sales targets, it could have ended up a huge financial disaster.  Fortunately, it wasn't.  And now, thanks to the leverage of higher production volumes, it will cost Apple less per handset to manufacture, and they are able to pass on the savings to consumers and expand the market.</p>

<p>But a vocal minority of iPhone customers started complaining, whining, and even suing Apple for dropping the price after it had been on the market a few months.  What do these people think the world owes them?  How reasonable is it to expect Apple to lock in the price just so they don't feel stupid for not being a little more patient?  How long should Apple have waited before consumers would have been happy with a price cut instead of being upset?</p>

<p>I think it was extremely generous of Apple to offer a $100 voucher, to placate these infantile customers.  In any case, they had the benefit and use of the product for those months.  How exactly have they suffered?</p>

<h2>Unlocking</h2>

<p>I can go out and buy a cheap subsidised phone, locked to a carrier.  It is a condition of sale.  It is the only way the company is able to offer the package without incurring a loss.  Sure, it would be <i>nice</i> to be able to choose any carrier, but for the iPhone, AT&T is the only game in town for now.  If you don't like it, don't buy it.</p>

<p>But then people complain that it's their device and they should be able to do what they want to it, including mess with its internals and trick it into using a different carrier.  Fine, go ahead - but you cannot expect Apple to support you, and you cannot expect future updates to continue to work with your hack applied.  It is difficult enough as it is to design and architect such a  complex system, and it would be nign impossible (not to mention unreasonable) for any supplier to provide fixes and new functionality, <i>and</i> provide workarounds that don't undo all these random hacks that have appeared.  Especially when some of the jailbreak techniques involve triggering security holes, they cannot expect a vendor to leave such an issue unfixed for their convenience.  Once you start patching the firmware, you have to accept that you're on your own.</p>

<h2>Third-party apps</h2>

<p>Apple has produced an amazing v1.0 product in the iPhone, a truly revolutionary device which has had an incredible impact on the mobile phone industry.  Obviously they have an internal SDK which their own developers use.  And obviously they want the phone to be more attractive with a wider selection of apps.  But there is a price to pay in releasing an SDK...</p>

<p>Before the SDK came out, they could evolve the system, frameworks and APIs and change them as much as they liked to fine-tune the system, as they only had their own apps to worry about.</p>

<p>As soon as Apple releases an SDK, they are making a huge committment, and the APIs are essentially set in stone, as third-party developers will start to rely on them.  Apple loses the freedom of changing, breaking, removing, and morphing the system.  It is quite rare to get v1.0 of anything designed just right, so I daresay it took so long to put out the SDK not because they wanted to alienate people, but to iron out the kinks and get it right as much as possible.</p>

<p>And now, as I write this update, Beta 6 has been published, Version 2 of the firmware is around the corner, and WWDC is nearly upon us.  It's a very exciting time for ISVs, and I only wish I had the time to work on an iPhone product.  Having done some embedded development in the past, I really enjoy that space, and I actually have several ideas for iPhone apps that I may one day get around to hacking on.</p>

<h2>Limitations</h2>

<p>So then the SDK comes out.  And once again, the pundits are out, nit-picking and complaining about its limitations.  People seem to focus one major issue: background processes.  And it is painfully obvious that those bandying about their opinions on such matters are ill-informed at best.  While the iPhone does an amazing job of providing a near-desktop user experience in a mobile device, it is still fundamentally a low-powered embedded computer.  And embedded development is simply <i>not</i> the same as developing for desktop applications, even though the tools, APIs and techniques are the same or very similar.  Apple has done an amazing job at providing a "Mobile Cocoa" toolchain, providing a platform that truly is years ahead of the other systems (such as Symbian or Windows Mobile).</p>

<p>Embedded development is characterised by what you <i>don't</i> have:</p>

<ul>
<li><b>Power</b>: the battery is a very finite and precious resource</li>
<li><b>Storage</b>: you can't assume you have many gigs of free space to play with.  A generous mobile device may only have a few meg available for <i>all</i> the apps to share.</li>
<li><b>Memory</b>: similar to storage, mobiles don't have much RAM to play with.</li>
<li><b>Processing power</b>: despite the rapid advances in low-power CPUs and integrated media decoding chips, mobile CPUs compromise processing power for power consumption, and err on the side of lasting longer.</li>
</ul>

<p>So the upshot of all this is that you have to think very carefully about your data structures so as not to consume too much precious RAM.  You have to be frugal with what you store to avoid filling up the user's memory stick.  You need to be conscious of the complexity of the algorithms and the amount of number-crunching you do to avoid loading up the CPU.  Simply put, the harder the CPU works, the more current it draws and thus the shorter the battery will last.</p>

<p>One developer who "gets it" is Craig Hockenberry, who wrote a <a href="blog entry">http://furbo.org/2008/03/16/brain-surgeons/</a> on this very topic.  He has been experimenting with the unofficial toolchains and has some direct experience and good advice to share.</p>

<p>At first, background processes sound like a great idea.  I've got dozens of things running in the background right now, monitoring things, updating thinks, blinking lights, and so on.  But they all consume power and resources, and this can be a killer on a low-power device.  So while one background process on an iPhone might not seem like such a big deal, consider if 6 of your beloved third-party apps decided to run something in the background?  The available memory for your foreground app is going to be massively limited, as there are 6 other hogs using up resources.  And kiss goodbye to your battery - even if they only wake up every minute or so to check something, those 7 apps could cause the CPU to be waking up every 10 seconds, which is going to chew up the battery very rapidly indeed.</p>

<p>These constraints have been placed there for very pragmatic reasons.  First of all, given many potential iPhone developers are coming from the desktop space with presumably little embedded experience, and Apple is understandably worried that people will develop big, slow, bloated and inefficient apps that hog the system and damage the user experience.  But more significantly, given this is a Version 1 product, it is far easier for Apple to impose constraints now and relax them later on than to later on take away something developers have come to rely on or expect.  I'd do the same thing in their shoes.</p>

<p>The iPhone is an incredible new platform, and hopefully as developers come up to speed with its peculiarities, they will also come to appreciate the care required not just in the hallmark of interface design, but also consider algorithm and data structure design to work within the constraints of the hardware.</p>]]>
    </content>
</entry>

</feed>

