<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Sean Kerwin dot org</title>
        <link>http://seankerwin.org/</link>
        <description>A geek with many Macs and no hair who spends his days writing C# code talks about nothing of any particular importance... and you&apos;re reading it?</description>
        <language>en</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Tue, 05 Jan 2010 17:42:47 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>The Largest Betamax Selection in Town!</title>
            <description><![CDATA[<p>Imagine that video rental shops worked like libraries; there's a whole network of affiliated branches, and if <i>this</i> library doesn't have it, they can get it at the cousin library across town and deliver it for you.  And as long as we're imagining, take it a step further: they can get it for you for no extra cost, absolutely <i>instantly</i>.</p>

<p>So that's the way video rentals work, and they all stock VHS cassettes, and that's that.  But now a sea change occurs: somebody invents DVDs.  All of the video rental shops start building their stock of DVD titles, and while doing so they take advantage of their affiliation network, so if your favored shop doesn't have <i>Joe Dirt</i> on DVD, they can get it from the shop across town.</p>

<p>But one little shop bucks the trend &mdash; even though DVD is the future, they decide to stick with VHS.  And that works out okay for them, because while the other rental shops are investing heavily in building a DVD library, they're making room by selling off their VHS cassettes, and this little dark-horse shop is gobbling them up like popcorn, and their library is <i>huge</i>.</p>

<p>Now it's ten years later.  Every video rental shop around the world has switched to DVD, but this little shop is still on VHS.  It's impossible to buy a VHS deck in stores, so this shop rents or sells you a VHS player when you sign up for membership, but that's okay actually &mdash; some people find that kind of convenient.</p>

<p>But now something interesting happens &mdash; a big, new, <i>hit</i> movie comes out... but only for DVD.  This little shop is caught-flat footed, because they simply can't compete here.  So what do they do?  They advertise!</p>

<p>This shop starts running ads, talking about how the local Blockbuster has a <i>tiny</i> library of titles, and it's absolutely terrible how small their library is.  Now, in a sense that's true; any individual Blockbuster may have a small library available, but keep in mind the affiliate network &mdash; when you get a DVD at Blockbuster, you may be getting it from any one of dozens of DVD rental places all over the world.</p>

<p>---</p>

<p>So what does any of that have to do with anything?</p>

<p>Well, VHS is the creaky old CDMA digital cellular technology.  DVDs are GSM, the modern cellular network architecture that almost every cellular carrier <i>around the world</i> uses.  Our hit DVD is obviously the iPhone.</p>

<p>And the tiny dark-horse video shop, that's Verizon.</p>

<p>Now, don't read this as a defense of AT&amp;T.  Personally I haven't had all that much trouble with them, but I know plenty of people who reflexively spit upon hearing those letters, and it's pretty clear that AT&T has been using their iPhone windfall to make <a href="http://www.penny-arcade.com/comic/2000/10/23/">money hats</a> rather than investing in their network infrastructure, and that's clearly subpar.  But while I dislike incompetence and don't care for spin, I absolutely <i>loathe</i> deception, and that's what Verizon's 'map' ads amount to, in my opinion.</p>

<p>The 'Verizon map' in those ads is, <i>by necessity</i>, a map of Verizon-owned-and-operated coverage zones; they <i>have</i> to be Verizon-owned-and-operated, because nobody else is running CDMA these days, just like nobody's using VHS or Windows 95.  The 'AT&amp;T map' to which they compare themselves, meanwhile, is of AT&amp;T-owned-and-operated coverage areas, which is not at all representative because AT&amp;T has reciprocal carriage agreements with GSM carriers throughout the US, and roaming agreements with GSM carriers <i>around the world</i>.</p>

<p>Personally, I can't stand Verizon &mdash; they have a policy of installing Verizon-controlled firmware on every phone they support, which tends to cripple the phone by removing built-in features to encourage you to use Verizon's expensive and inferior network-based equivalents.  Ever try to copy a ringtone to your Verizon phone using standard Bluetooth file transfer?  If you did, I'm betting it didn't go so well.  But Verizon does have a lot to offer customers, and if they want to be taken seriously they should compete by explaining the benefits of Verizon rather than deceiving people about the non-deficiencies of their competitors.</p>]]></description>
            <link>http://seankerwin.org/archives/2010/01/the_largest_betamax_selection.shtml</link>
            <guid>http://seankerwin.org/archives/2010/01/the_largest_betamax_selection.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Technology</category>
            
            
            <pubDate>Tue, 05 Jan 2010 17:42:47 -0500</pubDate>
        </item>
        
        <item>
            <title>Software Company Preventative Diagnostics</title>
            <description><![CDATA[<p>Ask each of your developers who the three best developers in the company are.  Only ask the developers &mdash; managers can't answer because they're in no good position to know.  Average out the votes and produce a consensus 'top three' list.  Hold on to it, and repeat the survey every six month.</p>

<p>If over a year has passed and two of those three people are still on the list, your company is probably screwed.  You might not actually have <i>realized</i> it yet, but that doesn't make it any less true.  Your management or business metrics may actually be positive, but if your development team isn't improving, the technology underlying everything is stagnating and sooner or later the smell will reach your customers.</p>

<p>Unless you already employ the best programers in the world, of course.</p>

<p>And if you really and truly believe that you employ the best programmers in the world, then unless your company name rhymes with 'Foogle', 'Schnapple', or 'Sicromoft', you're probably <i>really</i> screwed.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/12/software_company_preventative.shtml</link>
            <guid>http://seankerwin.org/archives/2009/12/software_company_preventative.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Thu, 03 Dec 2009 16:13:14 -0500</pubDate>
        </item>
        
        <item>
            <title>Asynchronicity in C#: Error Handlers and Completion Calls</title>
            <description><![CDATA[<p>Normal function calls are easy to write; you call <code>DoSomething( )</code>, it executes and returns, and you continue on your merry way.</p>

<p>Asynchronous function calls seem, at first blush, only a little more difficult &mdash; instead of calling <code>DoSomething()</code> and executing your follow-up code after it returns, you pass in a callback: <code>BeginDoSomething( Action callback )</code>.</p>

<p>So, problem solved, let's go home.  Unless you need a return value, that is.  But even then it seems simple; to turn a synchronous method like <code>int CalculateSomething( )</code> into an asynchronous method, you just pass it a delegate that takes a parameter: <code>void BeginCalculateSomething( Action&lt;int&gt; callback )</code>.</p>

<p>So is that it?  Nope.  Because all of that is wrong.</p>

<p>Even though the original <code>DoSomething( )</code> method had no return type, it still had a return <i>path</i> &mdash; it could throw an exception.  Let's imagine that <code>BeginDoSomething</code> looks something like this:</p>

<pre><code>
public void BeginDoSomething(Action callback)
{
    PrepareForLongRunningOperation( );
    
    ThreadPool.QueueUserWorkItem(
        delegate
            {
                LongRunningOperation();

                callback();
            });
}
</code></pre>

<p>A handy way to think about this sort of thing is to figure out where a thrown exception would emerge.</p>

<p>If something goes wrong within the call to <code>PrepareForLongRunningOperation</code>, that happens in the same context as the calling code &mdash; any exceptions will throw up to the calling code and come out of its call to <code>BeginDoSomething</code>.  The same applies to the call to <code>ThreadPool.QueueUserWorkItem</code> &mdash; no problem there.</p>

<p>But what if <code>LongRunningOperation</code> throws?</p>

<p><code>LongRunningOperation</code> would throw up into whatever internal part of the ThreadPool implementation actually launched it.  That exception can't come out of <code>ThreadPool.QueueUserWorkItem</code>, because by the time the asynchronous anonymous delegate is running <code>ThreadPool.QueueUserWorkItem</code> has already returned.  And since the exception can't come out of <code>ThreadPool.QueueUserWorkItem</code>, it also can't come out of <code>BeginDoSomething</code> &mdash; which means there's no way for the calling code to get the exception.</p>

<p>There are two main approaches to this problem &mdash; error handlers and completion calls.</p>

<b>Error Handlers</b><br />

<p>Instead of passing your begin method one callback, pass two: a callback to be invoked if everything goes to plan, and an exception-accepting callback to which errors will be passed.</p>

<pre><code>
public void BeginDoSomething(Action callback, Action&lt;Exception&gt; errorHandler)
{
    PrepareForLongRunningOperation( );
    
    ThreadPool.QueueUserWorkItem(
        delegate
            {
                try
                {
                    LongRunningOperation();
                    callback();
                }
                catch(Exception ex)
                {
                    errorHandler(ex);
                }
            });
}

// Sample usage:

BeginDoSomething(
    delegate
    {
		// Do something now that we're done
    },
    delegate(Exception ex)
    {
		// Do something with the error
    });
</code></pre>

<p>There are strengths and weaknesses to this approach.  The biggest strength of this model is that it <i>forces</i> the calling code to think about error handling &mdash; the prompt for it is right there in the method signature.  Error handling tends to fall through the cracks in any sort of code, but it's especially easy to overlook in an asynchronous context (It's also a lot more dangerous in an asynchronous context, because often dropping a callback invocation will cause a process to spin forever, sucking down resources and accomplishing nothing).</p>

<p>Separating the success case from the failure case may be either a strength or a weakness, depending on the particular task.  Sometimes it makes your code much cleaner, but it often happens that your success and error handler need to share context and implementation, which can make for some very ugly code.</p>

<b>Completion Calls</b><br />

<p>Instead of just invoking a parameter-less <code>Action</code> callback or a single-parameter <code>Action&lt;TReturn&gt;</code> callback, your code calls a single-parameter callback and passes it an <code>Action</code> or <code>Func&lt;TReturn&gt;</code> that the callback in turn invokes.</p>

<pre><code>
public void BeginDoSomething(Action&lt;Action&gt; callback)
{
    PrepareForLongRunningOperation( );
    
    ThreadPool.QueueUserWorkItem(
        delegate
            {
                try
                {
                    LongRunningOperation();
                    callback(delegate { });
                }
                catch(Exception ex)
                {
                    callback(delegate { throw ex; });
                }
            });
}

// Sample Usage:

BeginDoSomething(
    delegate(Action complete)
    {
        try
        {
            complete();
        }
        catch (Exception ex)
        {
            // Do something with the error
            return;
        }
        // Do something now that we're done
	})
</code></pre>

<p>At first blush, this seems like a much clumsier solution; you're essentially trusting the calling code to call your completion method.  That's true, at least in this case.</p>

<p>Where completion calls really shine are for asynchronous calls returning values; instead of calling their callback and handing in an <code>Action</code>, you call their callback and give it a <code>Func&lt;TReturn&gt;</code>, which they then <i>must</i> invoke to get their result.  That gives you an opportunity to throw exceptions that they <i>can't</i> cleverly bypass:</p>

<pre><code>
public void BeginCalculateSomething(Action&lt;Func&lt;int&gt;&gt; callback)
{
    PrepareForLongRunningCalculation();

    ThreadPool.QueueUserWorkItem(
        delegate
        {
            try
            {
                int result = LongRunningCalculation();
                callback(() =&gt; result);
            }
            catch (Exception ex)
            {
                callback(delegate { throw ex; });
            }
        });
}

// Sample Usage:

BeginCalculateSomething(
    delegate(Func&lt;int&gt; complete)
    {
        int result;
        try
        {
            result = complete();
        }
        catch (Exception ex)
        {
            // Do something with the error
            return;
        }
        // Do something with the content of result;
	})
</code></pre>

<p>Personally I prefer completion calls, mainly because the the pattern works so well for return values.  In practice, any time you need this sort of a pattern it's because you care about return values; if you need to ensure that X happens after Y, it's generally because X depends on the result of Y.  If X <i>doesn't</i> depend on Y, that's often a sign that you're being too linear in your analysis and that the tasks should be happening in parallel.</p>

<p>Microsoft seems to have collectively reached the same conclusion; <code>IHttpAsyncHandler</code>, the asynchronous methods off of <code>SqlCommand</code>, and the asynchronous forms of <code>WebRequest</code> all use the completion call approach.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/10/asynchronicity_in_c_error_hand.shtml</link>
            <guid>http://seankerwin.org/archives/2009/10/asynchronicity_in_c_error_hand.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Thu, 29 Oct 2009 13:27:42 -0500</pubDate>
        </item>
        
        <item>
            <title>Functional Programming</title>
            <description><![CDATA[<pre><code>public void BeginGetSingle(TIdentityCriteria identityCriteria, CompletionCallback&lt;TItem&gt; callback)
{
    TFilterCriteria filterCriteria =
        CriteriaUtilities.UpgradeCriteria&lt;TIdentityCriteria, TFilterCriteria&gt;(identityCriteria);

    RestClient.BeginGet&lt;TItem&gt;(
        CriteriaUtilities.CriteriaToUrl(
            filterCriteria,
            m_Map,
            m_ServiceUrlBase,
            r =&gt; typeof (TItem).FullName.Equals(r.OutputPayloadClass) &amp;&amp; r.AllowedVerbs.Contains(Verb.Get)),
        completionFunction =&gt; callback(() =&gt; completionFunction().Payload));        
}
</code></pre>

<p>My function takes a function and when done it calls that function, passing a function that the calling function calls for the result.</p>
<p>Now in fact my function calls another function taking a function accepting a function to call for its result, and to that function it passes a function which when called calls the first function passing a new function that when called calls the function that was passed to the function that my function passed to the other function, thereby returning the result of that function to the function that called my function.</p>
<p>And they say you can't write Lisp code in C#.</p> ]]></description>
            <link>http://seankerwin.org/archives/2009/10/functional_programming.shtml</link>
            <guid>http://seankerwin.org/archives/2009/10/functional_programming.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Tue, 27 Oct 2009 14:29:40 -0500</pubDate>
        </item>
        
        <item>
            <title>Xclan Night</title>
            <description><![CDATA[<p>Still a work in progress, but pretty cool looking already in my rarely-humble opinion.  The trick is to dim the red and green components while leaving the blue intact.</p>

<p><a href="http://dl.getdropbox.com/u/515062/xclan-night-9-4-09.png"><img src="http://dl.getdropbox.com/u/515062/xclan-night-9-4-09.png" alt="Xclan screenshot 1" style="width:100%" /></a><br />
<a href="http://dl.getdropbox.com/u/515062/xclan-night-9-4-09b.png"><img src="http://dl.getdropbox.com/u/515062/xclan-night-9-4-09b.png" alt="Xclan screenshot 2" style="width:100%" /></a></p>

<p>I'm trying to decide the best way to show text bubbles.  Everything's pretty scrupulously iPhone-friendly this time around (that's actually what got me started on Xclan again, figuring out how to work with UDP CFSockets in a run loop), but as I understand it uploading new text textures every few frames will bog an iPhone down pretty quickly.  I'm thinking of switching my NSOpenGLView to a CAOpenGLLayer and putting a bunch of CATextLayers on top for the bubbles.</p>

<p>There's actually an NSTextField in a layer in the game window; on Leopard it floats above the NSOpenGLView, but in Snow Leopard (where the screen shots were taken) it's invisible.  I haven't pursued it because I was planning on replacing the OGL view with a layer anyway, but it's a strange difference.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/09/xclan_night.shtml</link>
            <guid>http://seankerwin.org/archives/2009/09/xclan_night.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Clan Lord</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Fri, 04 Sep 2009 00:37:59 -0500</pubDate>
        </item>
        
        <item>
            <title>My Sister Is Like a Machine That Produces Straight Lines</title>
            <description><![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="taxes.png" src="http://seankerwin.org/images/taxes.png" width="531" height="389" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>]]></description>
            <link>http://seankerwin.org/archives/2009/08/my_sister_is_like_a_machine_th.shtml</link>
            <guid>http://seankerwin.org/archives/2009/08/my_sister_is_like_a_machine_th.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Humor</category>
            
            
            <pubDate>Sat, 01 Aug 2009 02:14:05 -0500</pubDate>
        </item>
        
        <item>
            <title>Just Chatting</title>
            <description><![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="MCK_Feminist.png" src="http://seankerwin.org/images/MCK_Feminist.png" width="435" height="600" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>]]></description>
            <link>http://seankerwin.org/archives/2009/06/just_chatting.shtml</link>
            <guid>http://seankerwin.org/archives/2009/06/just_chatting.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Humor</category>
            
            
            <pubDate>Mon, 29 Jun 2009 22:43:02 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone 3GS</title>
            <description><![CDATA[The 'S' stands for 'Stupidname'.<div><br /></div><div>I look at that name, and immediately it brings to mind the Apple IIGS (which stank). &nbsp;That then makes me think of the Apple III, which stank to high heaven. &nbsp;It's like somebody at Apple said, "hey, I know, let's give it a name evocative of our greatest corporate failures!"</div><div><br /></div><div>Seriously, the only worse name would've been the "iPhone Performanewton: Centris Edition". &nbsp;They could pair it with an eWorld membership and give it a built-in GeoPort Telecom Adapter. &nbsp;</div><div><br /></div><div>Maybe bundle an AAUI transceiver.</div><div><br /></div><div>Okay, I'm done.</div>]]></description>
            <link>http://seankerwin.org/archives/2009/06/iphone_3gs.shtml</link>
            <guid>http://seankerwin.org/archives/2009/06/iphone_3gs.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Humor</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Technology</category>
            
            
            <pubDate>Mon, 08 Jun 2009 16:59:23 -0500</pubDate>
        </item>
        
        <item>
            <title>Your Code Sucks, Please Stop Sucking</title>
            <description><![CDATA[<p>Dear Reader,</p>

<p>Your code sucks. </p>

<p>It's okay though, so does everyone else's code, including mine.  But a big part of improving is recognizing what you're doing wrong, and a big part of that is having random bald guys berate you.  So in the spirit of improving the world, here are five thoughts on writing code that sucks less.  Heavily C#-centric because that's what I've been reading lately, but I think most of it's meaningful in any environment modulo some terminological adjustments.</p>

<p><b>1. Dumb Comments Are Dumb</b></p>

<p>A comment that doesn't say anything useful is worse than worthless; it's actively harmful.<br />
	<br />
If you have a property named Marklar with a comment telling me that it 'gets or sets the Marklar', you haven't told me anything of value, and reading your useless comment has cost me precious seconds of my life that I'll never get back.  You've also probably raised my blood pressure a bit, but I suppose that's more on me than on you.</p>

<p>Now if a Marklar is an odd or confusing type of thing, and you can't reasonably expect everyone to know what it is or why it's there, by all means explain it.  Similarly, if this property has unusual behavior in some respect &mdash; perhaps it's lazily loaded &mdash; mention that in a comment.  But don't just put a bloody comment on every property because some never-been-employed professor once told you that that's the right thing to do.  It isn't.  If someone can't tell you that the <code>EyeColor</code> property lets you get or set the color of the receiver's eyes, they have no business writing code in the first place.</p>

<p>You should only put comments where they're needed, and generally if a comment is legitimately needed it's a sign that you're writing bad code.  Don't name the property <code>Age</code> and then add a comment explaining that it's in seconds; name it <code>AgeInSeconds</code> and skip the comment entirely.  That saves <i>you</i> typing, saves <i>me</i> reading, and has the further benefit of being completely impossible for future programmers to miss unless they're severely mentally impaired (in which case, see above, they have no business writing code in the first place).</p>

<p>Similarly, if you feel compelled to add a comment explaining that the next five lines of code are stochastically approximating the chronosynclastic infundibulumation of the yada, yada... that's your sign that those five lines should be extracted into a method with an appropriate name like 'AproximateTechnobabble'.  That makes it easier for me to read the original method because I can temporarily ignore the hard stuff, while also making it easier for me to understand the hard stuff later on if I need to (since it's now isolated with clear, labeled inputs).</p>

<p>Finally, dumb comments are dumb not just in the code, but everywhere.  If your checkin note is "I changed the twelfth character of line 37 from an 'e' to a 'z'", you have so completely and cleanly missed the point of checkin notes that I can't even scrape together a proper disparaging simile.  Checkin notes are there so I can get a high-level understanding of what you've checked in, <i>without having to open the bloody file</i>.  "Ran a match along a patch of bark" is a lousy checkin note when what you actually did was "burned down the forest".  Tell me about the forest, I couldn't care less about the <i>trees</i>.</p>

<p><b>2. Every Time You Type '#region' I Die A Little Inside</b></p>

<p>Regions suck.  If I were king I'd ban 'em outright, so sincere and total is my dislike.  They're a trick you play on yourself to let you pretend that your bad code is good, and they tell the world that you're a good enough coder to know a three-thousand-line file stinks, but that you're either not good enough to fix it or you're just plain too lazy.  In either situation the solution is to step up, not to add a region and sweep part of the bad code under the rug.</p>

<p>A special note on regions <i>within methods</i>: wrapping a region around your twelve constructors to hide the excess complexity is a venal sin.  Putting a region <i>inside</i> your method to hide 3,000 of its 4,000 lines is a <i>mortal</i> sin.</p>

<p>Some people might ask why extracting methods (like <code>AproximateTechnobabble</code> above) is good but collapsing regions within a method is evil.  The simple answer is encapsulation; a region isn't a new scope, so it has access to all the fields and variables of the method it's within.  That greatly increases the difficulty of understanding the code, because now I need to actively read through and figure out how the code inside the region interacts with the code outside the region.  An extracted method doesn't have the problem, because I can look at exactly what parameters are passed in and exactly what comes out, without having to trace through and worry about side effects.  Regions superficially seem to simplify the complexity of your code; extracted methods <i>actually do</i>.</p>

<p><b>3. Static Methods Are Your Friends, And You Should Want More Of Them</b></p>

<p>Static methods are pure functions, in the mathematical sense; they're black boxes that take some input and return some output.  Remember where I said methods are better than regions because they simplify complexity?  The same logic recommends static methods over non-static methods.  Static methods help you make sure you're not weaving a tangled web of side effects and dependencies with each method call.  </p>

<p>Imagine coming upon a call to <code>myComplexMarklar.CalculateInfundibulumation()</code>.  Now, if you don't know what infundibulumation is (incidentally, the state of being or the act of becoming funnel-like or akin to a funnel), and have no idea how you would calculate it (no idea), that method doesn't tell you a whole lot.  Now imagine stepping through that rather lengthy method and figuring out how it works.  You are potentially entering a world of pain.</p>

<p>Now imagine a static method, <code>Marklar.CalculateInfundibulumation(float topRadius, float bottomRadius, float height)</code>, and further imagine that the non-static method works by calling the static method and passing along the three appropriate values.  It has instantly become a whole lot easier for me to understand what infundibulumation is, because now I know that no matter how gnarly the math is it's just a function of those three values.  Now not only can I better understand that particular method, but a lot of the meaning of the Marklar class in general has become more clear.</p>

<p>In an object-oriented language, every instance method is getting more parameters than you've listed in the declaration line; it's also getting access to all of the instance's member fields.  Imagine seeing that written out &mdash; would you deliberately write a method that takes a hundred parameters but only uses two of them?  That might be a good sign that it's time for some judiciously-applied static methods.</p>

<p>Static methods have other benefits.  For one, they're a lot more reusable; if the static <code>CalculateInfundibulumation( tR, bR, h )</code> method is general, you might find you need it in another class.  Depending on your situation, you could either make it public and call it right out of Marklar, move it to a new common base class, or move it to a utility class.  Each of those solutions would be far more complicated if it were non-static.  I've been in situations where I needed a complex non-static method from a pre-existing class that I couldn't reasonably modify, and ended up constructing an instance with a bunch of bogus data, setting the handful of fields that the calculation actually depends on, and calling the instance method on that.  That's hideous &mdash; ugliness wrapped in brittleness wrapped in unmaintainable complexity.  Don't make me do that again.</p>

<p>Static methods also lend themselves incredibly well to a form of optimization known as <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>.  The root of memoization is basically the realization that the next time you run the same calculation, you'll reach the same result (yeah, I know, 'duh', right?).  The tie-in to static methods is that static methods let you know precisely <i>what</i> the inputs are to the calculation you're running, while instance methods don't.  Memoizing a static method is 'easy' (in the sense of being a solved problem), while memoizing instance methods can be a buggy pain in the butt.</p>

<p><u>3b. Subverting Static Methods Is Bad And People Who Do It Should Be Forced To Write Pascal</u></p>

<p>Sometimes you'll see a static class, full of static fields and static variables and static methods.  That's not what I'm talking about when I say static is good.  That's not good, it's the other thing.  Bad.  It's a crappy-ass degenerate-global-variable-singleton.  Don't do that.  <a href="http://steve.yegge.googlepages.com/singleton-considered-stupid">Smart people hate singletons</a>.</p>

<p><br />
<b>4. Properties Are Properties, Methods Are Methods</b></p>

<p>A property is intended to represent an attribute of an object, while a method models an action that the object may take or that may be taken upon the object.  These are different concepts, and you need to think about which is appropriate for a particular case.  If you have a property with a verb in the name, you're almost certainly thinking about things the wrong way.</p>

<p>Some people will tell you that properties should just be get/set wrappers around your fields.  Others will say it's okay to do some field validation.  Others go hog wild.  It's hard to draw bright lines because the simple fact is that it's sometimes a judgement call.  A good heuristic is to think like someone using your class.  The default assumption is that properties are simple get/set wrappers around a private field, and everything you do to violate that assumption nudges the scale towards building a method.</p>

<p>Let's say your class has a <code>ServerConnection</code> property that returns some sort of communications channel to a remote server.  As a caller, my mindset is that this connection already exists, and the property is giving me access to it.  But if only a subset of the calling code ever needs this connection, it might make sense to lazily connect when the property is first accessed rather than connecting in the constructor and keeping around a connection that may never actually be needed.  But that's changing the semantics of the property a little bit, because the mindset of the calling code is still 'this already exists, the property is just handing it to me', and the calling code may not expect this property to take a long time to execute.  Maybe now there should be a progress bar, or the call should happen in another thread.</p>

<p>Like I said, judgement call.  In situations like that one, asking ten developers will get you fifteen different opinions.  There isn't a 'right' answer, it's just a matter of getting it right enough.  All anyone can ask is that you think.</p>

<p>But in other cases, it's totally cut and dried.  I've seen code with a LastSaveDate property that saves to the database and returns DateTime.Now.  If you're not physically ill at the thought of that, you need to figure why and <i>get sick fast</i>.</p>

<p><b>5. Public Methods Are Contracts, Which Should Not Be Entered Lightly</b></p>

<p>When you make a method public, you're inviting the world to use it and you're promising that it will continue to do exactly what it does now.  Forever.  </p>

<p>Let's say you're creating a <code>CarFactory</code> class that creates new <code>Car</code> objects.  <code>CarFactory.CreateCar( )</code> was starting to get a little long, so you started extracting out helper methods: <code>CreateTransmission( )</code>, <code>CreateBody( )</code>, <code>CreateWheel( )</code>, etc.  That's good, keep doing it.</p>

<p>Now let's say you decided that since <code>CreateCar( )</code> was public that you might as well make <code>CreateTransmission( )</code> <i>et al</i> public too.  That's no-so-much with the good.  Unless you know right now that someone else needs to create a transmission without creating a full car, leave that method private.</p>

<p>To the calling code, a <code>CarFactory</code> and a <code>Car</code> are black boxes.  The calling code doesn't need to know that a car contains a transmission, and next year when you change <code>CarFactory</code> and Car to build fully-electric vehicles, which don't <i>need</i> a transmission, you won't have to worry about supporting that public method that a bunch of your coworkers have just spent twelve months linking against.</p>

<p>There's a more general lesson here: Share the hot dog, not the making thereof.</p>

<p>Which, come to think of it, is a good moral on which to end any story.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/05/your_code_sucks_please_stop_su.shtml</link>
            <guid>http://seankerwin.org/archives/2009/05/your_code_sucks_please_stop_su.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Fri, 29 May 2009 23:08:42 -0500</pubDate>
        </item>
        
        <item>
            <title>Twit, Twit, Twit</title>
            <description><![CDATA[<p> I 'got' Twitter pretty quickly, because I was actually using it before it existed.  I used to carry on lossy low-priority conversations with people via AIM status messages; it was a good way to say stuff that wasn't important enough to warrant a message and also to broadcast things in the vein of "hey, here's a fun link" without needing to directly spam people.</p>

<p>I'm pretty sure this is roughly what the designers of Twitter had in mind, incidentally.  If you take a look at the XML or JSON feeds provided by the Twitter API, each individual tweet is actually called a 'status' &mdash; the URI for a particular tweet is <code>&lt;username&gt;/status/&lt;some_big_number&gt;</code> &mdash; the <code>&lt;OL&gt;</code> element that contains the tweets on Twitter HTML page is of CSS class 'statuses'... the list goes on.  Obviously the original intent of the tool doesn't define what the tool is actually used for &mdash; I don't think AIM away messages were intended as an out-of-band communications protocol, at least at first &mdash; but it's interesting nonetheless.</p>

<p>What's also interesting is that Twitter users seem to fall into two separate and largely non-overlapping groups.  Group A are people using it much like I am, as a non-ACKed broadcast medium for random thoughts that aren't important enough for a reliable messaging protocol like IM, email, or a blog post.  Group B are the people who see Twitter as a marketing/communication tool that will allow them to get the word out to members of Group A, for whatever value of 'the word' is meaningful to them.</p>

<p>I see three ways this can go: either the two groups diverge completely and group B develops a self-sustaining ecosystem of their own; or group B recognizes that marketing in this context is futile and dwindles and dies; or group B is so persistent in their efforts that group A abandons Twitter and finds a new bicycle.</p>

<p>If you get the 'new bicycle' thing, you're definitely in group A, though not getting it doesn't necessarily relegate you to group B.</p>

<p>But if you <i>know</i> you're in group B and want to understand group A, then you should figure out what it means, why you don't get it, and what you can do to make sure you get to autotune the <i>new</i> new bicycle... and then despair of ever marketing effectively on something like Twitter.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/05/twit_twit_twit.shtml</link>
            <guid>http://seankerwin.org/archives/2009/05/twit_twit_twit.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Technology</category>
            
            
            <pubDate>Sat, 09 May 2009 00:53:56 -0500</pubDate>
        </item>
        
        <item>
            <title>Constant Documentation</title>
            <description><![CDATA[<p>The only C++ feature I seriously miss in other languages is <code>const</code>.  Not in the simple 'this variable is a constant' usage, where it's nothing but a type-checked #define &mdash; no, I miss the <code>const</code> keyword in the interaction of <code>const</code> methods and <code>const</code> objects.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>First some background &mdash; I don't expect folks who haven't spent time with C++ to know much about this, and a surprising number of veteran C++ coders seem to be unaware of it as well.  In C++, <code>const</code> can be many things.  One role is as a type modifier that means "I'm not going to change this".  A common usage is to accept a <code>const</code> references:</p>

<pre><code>
int calculateAverage( const std::vector&lt;int&gt; &amp; values );</code></pre>

<p>That <code>const</code> means "I'm just going to look at it, I'm not going to mutate it" (or, if you like thinking functionally, "I'm a real function, hand me my immutable input" &mdash; more on that angle later).  What does that mean, in terms of actual code?  It means the body of that function can't call (for instance) <code>values.push_back( 12 )</code> and mutate the data it was handed.  And when I say "can't" I don't mean "shouldn't", I mean the compiler will actually flag that as an error and stop you.  If you keep trying it'll even call you names.</p>

<p>Now obviously the body of the function still needs a way to call methods on that vector &mdash; it'll need some to get at the contents, whether it's running a for loop from zero to <code>values.size( )</code> and calling <code>operator[]</code> in between, or looping from <code>begin()</code> to <code>end()</code>, or whatever.  So what makes those methods okay, and <code>push_back</code>, <code>pop_back</code>, <code>insert</code>, <code>swap</code> and various other mutators verboten?</p>

<p>The answer (as you've doubtless cleverly deduced already) is the <code>const</code> keyword.  In C++ <code>const</code> isn't just a type modifier for variables and parameters, it's also a permitted modifier on methods too.  The <code>size( )</code> method on an array is declared like this:</p>

<pre><code>
size_type size() const</code></pre>

<p>That <code>const</code> means "you can call me on a constant object, object reference, or object pointer!  I promise I'm safe!".  And that isn't an idle promise, it's a promise enforced by the compiler.  If you declare a <code>const</code> method in a class and then try to alter member variables, the compiler's going to call it an error (unless that member is declared as volatile, but that's getting into advanced C++ and beyond what I'm interested in talking about here).</p>

<p>The final crucial piece of the big, tasty, onst-in-C-plus-plus-pie is the fact that you can overload by <code>const</code>-ness.  The aforementioned <code>std::vector</code> actually declares not one but <i>two</i> <code>operator []</code>s (or should that be '<code>operator</code>s <code>[]</code>'?), one of which returns a reference to the space in the underlying array, and one of which returns the simple value.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>So that's what I mean by <code>const</code> when I say "I like <code>const</code> in C++".</p>

<p>The usual justification for this feature set is efficiency; the compiler can differentiate between <code>const operator[]</code>, which returns a simple value, and non-<code>const operator[]</code>, which must return either a reference to an internal data structure or a proxy object, neither of which is necessarily easy or fast.</p>

<p>But me, I like <code>const</code> for a different reason.  And that's documentation.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>Backwards digression, the second: Defining the types and parameters of a function or method isn't a fundamental necessity; you could define a language where functions access the parameters they were passed by indexing into an array and assuming things are where they belong.  It's very easy to do this in JavaScript, for example &mdash; the language doesn't verify parameters, and a function is free to get them out of the local <code>arguments</code> array:</p>

<pre><code>
function sayHello() {
	alert("Hello, " + arguments[0] + "!");
}
sayHello('World');
</code></pre>

<p>There are two reasons to specify type parameters; to tell the compiler the semantics of the function, and to tell the human reading the code the semantics of the function.  I'm phrasing those in parallel for a reason, because they're two aspects of the same principle; function argument lists exist to document the code.  This just happens to be one of the (distressingly rare) cases where the documentation is so intrinsic to the language that we don't realize it's documentation.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>There's something special in that.  Microsoft recognizes how important self-documenting code is; that's how <a href="http://en.wikipedia.org/wiki/IntelliSense">IntelliSense</a> works, and I think you (or I, at least) could argue very plausibly that (a) the entire .NET architecture can be viewed as a means to improve and extend IntelliSense and (b) this may well represent Microsoft's biggest strategic advantage over its competitors.  The core idea that makes IntelliSense work is that the best documentation of the code is the implementation itself; the more information you can mine out of that, the better.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>The back-end of one of my employer's new (award-winning!) products is a suite of <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a> web service APIs.  One of the core parts of any such system is the routing engine; given the URI of an incoming request, how do we map that to the bunch of code that represents the appropriate response?  Our system uses XML-formatted resource maps that contain the information necessary to do that; a resource map contains not only URI paths, but the parameters to extract from those URI paths and the types of those parameters, as well as the required and optional query parameters and <i>their</i> types... it's pretty rich and pretty nifty.</p>

<p>But the <i>really</i> nifty part is that I had a moment of insight one day and realized I could hardcode a mock resource into the router that ran the resource map through an <a href="http://en.wikipedia.org/wiki/XSLT">XSL transformer</a> and returned a pretty (or at least, legible) HTML page that documents the system.  Every URI, every parameter, all right there.</p>

<p><i>And</i> &mdash; and this is the important bit &mdash; <i>nobody ever has to worry about updating this documentation</i>.  It's automatically derived from the actual implementation of the system; to add something new to the system, you need to add it to the resource map, and <i>bam</i>, there it is in the help page.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>This sort of implementation-derived documentation is the primary advantage that strong, static typing has over more dynamic approaches.  IntelliSense for a more dynamic language means your either execute the code as it's being typed and use real-time introspection (<a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html">as proposed by Steve Yegge in a talk at Stanford</a> &mdash; and probably other places, but that the first time I saw it in print) or you start trying to layer a more static type system on top of them.  Either way has its problems.  Running the code so you can IntelliSense it has sandboxing problems, particularly if you're doing anything that's concurrent or distributed, and laying a static type system on top of a dynamic type system is kind of an advanced, compiler-powered form of missing the point, if you ask me.  I have a lot of vaguely-connected thoughts on that last point that I should probably bundle together at some point.  The <i>Readers' Digest</i> version is that adding classes to JavaScript is like adding wheels to a unicycle, in that your 'addition' has the unavoidable side effect of squashing what made the original unique.  But that's a rant for another day.</p>

<p>Languages like C#, C++, and Java don't have those problems when it comes to rich syntax acting as embedded documentation.  It's still not easy, but it's a well-studied problem, and there's existing code you can point to and say "here, here's where that feature goes!".</p>

<p>And it is happening, albeit slowly.</p>

<p>Generics in Java are widely (and correctly) criticized for not being integrated into the VM the way .NET 2.0 generics are, but on the other hand they do serve as a form of compiler-checked documentation; <i>this</i> <code>ArrayList</code> is of <code>Marklar</code>s, and <i>that</i> <code>ArrayList</code> is of <code>Widget</code>s.  The compiler will force me to keep those types distinct, and I can look a method signature and know what it expects.  Yes, it's really just an annotation for the programmer and the compiler and doesn't actually change the generated code, but in a sense that's exactly the <i>point</i> &mdash; <code>const</code> in C++ doesn't change the generated code either most of the time, it's just letting programmers express both constraints and intent in a richer and more robust fashion.</p>

<p>Critics of static typing frequently argue that it provides a false sense of security, and they're right to an extent.  But that doesn't mean that static typing is bad, it simply means that static typing is insufficient.  Choosing between compiler-powered semantic tests and human-written unit tests is akin to choosing between seat belts and airbags &mdash; the <i>correct</i> choice, anticlimactic though it may seem, is <i>both</i>.</p>

<div style="text-align:center;">&bull; &bull; &bull;</div>

<p>So what's my point?  Good languages let me do more than just write code, they let me codify what I expect my code to do and how I expect other code to call it.  It lets me express in a simple and clear form every assumption I'm making, and then it explicitly checks my assumptions with all the thoroughness it can muster.  That's important today for writing good code, and it's only going to get more important.</p>

<p>Imagine syntax-level support for concurrency.</p>

<p>There are methods in the next version of <a href="http://seankerwin.org/iclan">iClan</a> that are designed to only be called on the main thread; any time I want to activate them from elsewhere I call <code><a href="http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:">performSelectorOnMainThread:withObject:waitUntilDone:</a></code> (boy that's a mouthful).  If Objective-C had syntax for concurrency, I could mark my methods as '<code>mainthreadonly</code>', and the compiler could stop me from calling them from elsewhere.  Or better yet, the compiler could note from the headers that the UI-related methods I'm calling in those methods are <code>mainthreadonly</code>, and from that <i>deduce</i> which of my methods must be <code>mainthreadonly</code>, and either warn me for not labeling them or just cascade the analysis all the way up the call graph.</p>

<p>Similar story:  I recently built a lockless queue in C#; it's built around <a href="http://blogs.msdn.com/ericlippert/archive/2007/12/10/immutability-in-c-part-four-an-immutable-queue.aspx">Eric Lippert's immutable queue</a> code, and it uses <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange.aspx">Interlocked.CompareExchange</a></code> to swap a new immutable value for the old immutable value (Or rather, it repeatedly <i>tries</i> to make that swap, regenerating a <i>new</i> new immutable queue from the new old immutable queue if it fails... It's fun code, I should write about it someday &mdash; it turns out not to be terribly <i>useful</i>, but fun nonetheless.).  The exercise would've been a lot easier on a lot of levels if C# gave the <code>const</code> keyword all the magic powers it has in C++.</p>

<p>You'll notice both of those examples have a concurrency angle, and that's not a coincidence.  All of the self-anointed experts agree that the age of concurrency is upon us, and for a change the experts who <i>aren't</i> self-anointed and are too smart and humble to actually <i>call</i> themselves experts and the nobodies like myself seem to be in pretty general agreement with them.  And the thing about concurrency and distributed system is, well, they're hard.  Maybe not hard like <i>NP-hard</i> hard, but still pretty bloody difficult.  And the more the compiler and the runtime and the VM and the OS can do to check our work for us, the better.</p>]]></description>
            <link>http://seankerwin.org/archives/2009/05/constant_documentation.shtml</link>
            <guid>http://seankerwin.org/archives/2009/05/constant_documentation.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">C++</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Thu, 07 May 2009 16:54:01 -0500</pubDate>
        </item>
        
        <item>
            <title>Generic Accumulators in C#</title>
            <description><![CDATA[ <p>I fell down a chain of links today and wound up reading <a href="http://www.paulgraham.com/icad.html">one of Paul Graham's numerous pro-Lisp essays</a>.  I responded as I typically do by attempting to implement his examples in whatever language I have handy, which today was C# 2.0.</p>

<p>The example Graham cites in the appendix is a function for generating accumulators:</p>

<code><pre>(defun foo (n)
  (lambda (i) (incf n i)))
</pre></code>

<p>For those of me who always find reading Lisp akin to reading the opening chapters of the Bible (but with parentheses standing in for the voluminous 'begats'), he also helpfully provides equivalents in a few other languages, such as JavaScript:</p>

<code><pre>function foo(n) { 
  return function (i) { 
		   return n += i } }
</pre></code>

<p>An accumulator is a function that maintains internal state; when you invoke it with a new value it adds that value to its internal state and returns the new sum.  An example usage would be to initialize it to zero and invoke it with each value in an array of integers; the result of the final invocation would be the sum of the integers -- or rather, the accumulation of the values.</p>

<p>For instance:</p>

<code><pre>var myAcc = foo(0); // Initialize to zero
myAcc(1); // 0 + 1 = 1
myAcc(10); // 0 + 1 + 10 = 11
myAcc(44); // 0 + 1 + 10 + 44 = 55
</pre></code>

<p>So, can we build that in C#?  The answer is an enthusiastic 'kinda'!</p>

<code><pre>[TestFixture]
public class AccumulatorTest
{
	private delegate int Accumulator(int inc);

	private static Accumulator MakeAccumulator(int start)
	{
		int n = start;

		return delegate(int inc)
		{
			n = n + inc;
			return n;
		};
	}

	[Test]
	public void TestAccumulator()
	{
		Accumulator acc = MakeAccumulator(0);

		Assert.AreEqual(0 + 0, acc(0));
		Assert.AreEqual(0 + 0 + 1, acc(1));
		Assert.AreEqual(0 + 0 + 1 + 10, acc(10));
		Assert.AreEqual(0 + 0 + 1 + 10 + 44, acc(44));
	}
}
</pre></code>

<p>It's not actually that long -- the <code>TestAccumulator</code> function at the bottom is a quickie NUnit test case to verify it's doing what I think it should.  It's still longer than the Lisp or JavaScript version though.</p>

<p>But there's one other major difference from those versions -- typing.  The C# version only works on integers, whereas the Lisp and JavaScript version will work on anything that can be added.  But if we try to genericize the C# code we'll run into problems at the <code>n = n + inc</code> statement, because you can't add two objects and thus can't add two generic objects without a generic constraint guaranteeing you can.  And since there's no <code>IAddable</code> interface that integers and floats and strings and everything implement (and since C# still doesn't have a more generalized form of <code>where</code> clause that would let us specify constraints as duck types rather than static types), we're basically SOL with a generic C# accumulator.</p>

<p><i>Or are we?</i> (Bum-bum-<b>BUM</b>!)</p>

<p>What if we passed our <code>MakeAccumulator</code> function two parameters: a starting value, and a delegate function to use for incrementing?</p>

<code><pre>[TestFixture]
public class AccumulatorTest
{
	private delegate T Accumulator&lt;T&gt;(T inc);

	private delegate T AccumulationDelegate&lt;T&gt;(T a, T b);

	private static Accumulator&lt;T&gt; MakeAccumulator&lt;T&gt;(T start, AccumulationDelegate&lt;T&gt; accumulationDelegate)
	{
		T n = start;

		return delegate(T inc)
		{
			n = accumulationDelegate(n, inc);
			return n;
		};
	}

	[Test]
	public void TestIntAccumulator()
	{
		Accumulator&lt;int&gt; acc = MakeAccumulator(0, delegate(int a, int b) { return a + b; });

		Assert.AreEqual(0 + 0, acc(0));
		Assert.AreEqual(0 + 0 + 1, acc(1));
		Assert.AreEqual(0 + 0 + 1 + 10, acc(10));
		Assert.AreEqual(0 + 0 + 1 + 10 + 44, acc(44));
	}

	[Test]
	public void TestFloatAccumulator()
	{
		Accumulator&lt;float&gt; acc = MakeAccumulator((float)0, delegate(float a, float b) { return a + b; });

		Assert.AreEqual(0 + 0, acc(0));
		Assert.AreEqual(0 + 0 + 1, acc(1));
		Assert.AreEqual(0 + 0 + 1 + 10, acc(10));
		Assert.AreEqual(0 + 0 + 1 + 10 + 44, acc(44));
	}

	[Test]
	public void TestStringAccumulator()
	{
		Accumulator&lt;string&gt; acc = MakeAccumulator("", delegate(string a, string b) { return a + b; });

		Assert.AreEqual("" + "", acc(""));
		Assert.AreEqual("" + "" + "marklar", acc("marklar"));
		Assert.AreEqual("" + "" + "marklar" + "smurf", acc("smurf"));
		Assert.AreEqual("" + "" + "marklar" + "smurf" + "foo", acc("foo"));
	}
}
</pre></code>

<p>Yay!</p>

<p>So what is it good for?  Absolutely nothing!  But it sure was fun!</p>]]></description>
            <link>http://seankerwin.org/archives/2008/12/generic_accumulators_in_c.shtml</link>
            <guid>http://seankerwin.org/archives/2008/12/generic_accumulators_in_c.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Javascript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Wed, 31 Dec 2008 11:29:43 -0500</pubDate>
        </item>
        
        <item>
            <title>Programming For the Easily Amused: Part 1</title>
            <description><![CDATA[ <div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-family: -editor-proxy;">For a long time I've semi-seriously joked about writing a humorous non-theoretical book about computer science that isn't a total crock. &nbsp;I think I've finally decided that the easiest thing to do is break the entire field down into a random series of blog posts that will in all likelihood never actually be collected into a book. &nbsp;So here's the preamble.</span></span></div><div><br /></div><div>So what is programming? &nbsp;Programming a computer is all about explaining to a computer how to do things. &nbsp;The big secret all programmers share is that computers are dumb. &nbsp;Really dumb. &nbsp;But -- and this is why we keep them around -- infallibly obedient and really, really good at math. &nbsp;Have you ever called a tech support or customer service line and had to put up with a dolt who can't do anything but follow the script in the big-honking-binder his supervisor gave him on his first day? &nbsp;Now imagine that guy with a calculator, and you're imagining someone maybe ten or twenty times smarter than a computer. &nbsp;The job of the programmer is to write that big-honking-binder.</div><div><br /></div><div>So if you're writing a big-honking-binder for your new friend the phone drone, what kind of instructions can you put in there? &nbsp;If your employees were intelligent and informed, you wouldn't need much: just a single sheet of paper that says 'handle customer issues' at the top, and voila, you're done! &nbsp;But remember, the computer you're programming here is stupid, and he's not going to understand high-level instructions like that. &nbsp;You need to break it down:</div><div><br /></div>
<ol>
<li>
	Ask the caller whether he or she currently owns a product.
	<ol style="list-style-type: upper-alpha;">
		<li>If the caller says 'yes', go to step 2.</li>
		<li>If the caller says 'no', go to step 5.</li>
	</ol>
</li>
<li>
	Ask the caller what is wrong with the product.
	<ol style="list-style-type: upper-alpha;">
		<li>If the caller says 'it will not turn on', go to step 3.</li>
		<li>If the caller says 'it will not turn off', go to step 4.</li>
	</ol>
</li>
<li>Tell the caller how to turn the product on.  Hang up.</li>
<li>Tell the caller how to turn the product off.  Hang up.</li>
<li>Tell the caller where to buy the product.  Hang up.</li>
</ol>
<br />
<div>If you look at that script, you'll probably notice a few things (besides the fact that we're training our human computer to be unbearably rude). &nbsp;What if the answer to step one is "I don't know"? &nbsp;Different people (computers) might handle that differently. &nbsp;Some might hang up; some might continue on to step two; some might ask question one over and over until the frustrated customer picks 'yes' or 'no' (we'd call that "undefined behavior", which basically means we don't know in advance what's going to happen; undefined behavior is a source of some pretty nasty bugs). What if there's something wrong with the product besides an inability to turn it on or off? &nbsp;What if the product won't turn on because it's broken?</div><div><br /></div><div>Those are all bugs in our program, and they all serve to show part of what makes programming difficult; decomposing a task ('make customers happy') into tiny little steps that a mindless automaton can follow is very difficult. &nbsp;You can't count on a computer to make a value judgement; you can't count on a computer to recognize that 'yeah' or 'yup' also mean 'yes'; you can't count on a computer to do much of anything except for faithfully following whatever flawed or incomplete script you give it. &nbsp;That and math.</div> ]]></description>
            <link>http://seankerwin.org/archives/2008/12/programming_for_the_easily_amu.shtml</link>
            <guid>http://seankerwin.org/archives/2008/12/programming_for_the_easily_amu.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Humor</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programming</category>
            
            
            <pubDate>Tue, 02 Dec 2008 15:47:38 -0500</pubDate>
        </item>
        
        <item>
            <title>The Morning After</title>
            <description><![CDATA[<div>As a conservative, I understand that our rights are not free; &nbsp;we pay for them every day.</div><div><br /></div><div>The price of capitalism is that the vicissitudes of the market may leave good men down or line the pockets of the undeserving. &nbsp;The price of free speech is that I must endure the discordancy of lies mingling with truth. &nbsp;And the price of democracy is the ever-present possibility that the candidate I favor may fall before the candidate I do not.</div><div><br /></div><div>And, having spent eight years deafened by the omnipresent din of untrue and unfair accusations against President Bush, I recognize that the price I pay for resenting those slings and arrows is the ethical obligation to give President Elect Obama a fair chance to prove himself in office.</div><div><br /></div><div>All of these prices, and the many other prices I must pay for my freedom, I pay willingly.</div> ]]></description>
            <link>http://seankerwin.org/archives/2008/11/the_morning_after.shtml</link>
            <guid>http://seankerwin.org/archives/2008/11/the_morning_after.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Politics</category>
            
            
            <pubDate>Wed, 05 Nov 2008 10:03:22 -0500</pubDate>
        </item>
        
        <item>
            <title>Wikis Are Irish Roadsigns</title>
            <description><![CDATA[My family has a running joke that the road signs in Ireland are there to remind you of things you already know rather than to direct you to places you've never been. &nbsp;If you've never been to Ireland you'll think I'm exaggerating, but the signs really are just a step short of saying "the place where Mary brought that lovely jacket - 12 km".<div><br /></div><div>It's even worse if you stop and ask for directions - "Oh, you'll be wantin' to take that lane just past Brian's house, you know, Brian with the dog!" &nbsp;It takes about fifteen minutes to convince your erstwhile directioneer that you don't in fact know Brian, having spent the majority of your life on the other side of the Atlantic Ocean, and that you'll really need your instructions expressed in a format that doesn't presuppose knowledge of the local geography so intimate as to render directions unnecessary. &nbsp;At which point you'll be given a confusing array of rights, lefts, and reverses, followed inevitably by "and then it's right up the road, you can't miss it!", which you'll dutifully follow in a large circle before returning, six hours later, to ask the exact same gentleman for directions.<div><br /></div><div>In general he'll pretend to have never before made your&nbsp;acquaintance&nbsp;and eventually (after repeating the previously-rendered fifteen-minute protestation of your non-acquaintance&nbsp;with Brian's dog) give you an entirely new and completely&nbsp;dissimilar&nbsp;set of instructions that will culminate in your accidental arrival in Paris.<div><br /></div><div>I'm not entirely sure how one manages to drive from Ireland to mainland Europe, but it happens, I <span class="Apple-style-span" style="font-style: italic;">swear</span>.</div><div><br /></div><div>But anyhoo, my point is that Irish road signs are designed to remind you of things you already know, or provide you with details about subjects on which you already have high-level understanding. &nbsp;And Wikis are exactly the same way; they make excellent references, but they're largely terrible as first-order sources or methods of communicating information, primarily because of the structure they inspire - the same disaggregated, freeform organization that makes it possible to deep-dive into related matters as a reference makes it very difficult to arrange information in the sort of cohesive sequence necessary to teach people something new.</div><div><br /></div><div>Learning something new is akin to recording every lecture in a college course and playing them back in a random sequence - even though every note may be hit, it's not precisely musical.</div><div><br /></div><div>All of which means precisely nothing, except that I haven't posted in a while and this was the only interesting and non-proprietary thought in my head.</div><div><br /></div></div></div>]]></description>
            <link>http://seankerwin.org/archives/2008/10/wikis_are_irish_roadsigns.shtml</link>
            <guid>http://seankerwin.org/archives/2008/10/wikis_are_irish_roadsigns.shtml</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Humor</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Technology</category>
            
            
            <pubDate>Mon, 06 Oct 2008 18:33:19 -0500</pubDate>
        </item>
        
    </channel>
</rss>
