<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5322535968700669808</id><updated>2011-12-15T13:56:47.220-08:00</updated><category term='wiki'/><category term='documentation'/><category term='w3c is not people'/><category term='narcissism of minor differences'/><category term='management software'/><category term='programming'/><category term='.Net'/><category term='requirements documents'/><category term='pylot'/><category term='wtf'/><category term='literacy'/><category term='bonuses'/><category term='software development'/><category term='interface'/><category term='software architecture'/><category term='enterprise software'/><category term='t-file'/><category term='text'/><category term='i am one of the greatest designers of all time'/><category term='agile'/><category term='unintentional irony'/><category term='qa'/><category term='marginal utility'/><category term='python'/><category term='code smell'/><category term='picture time'/><category term='unit testing'/><category term='interviews'/><category term='oracle killed my family'/><category term='cycling'/><category term='money money money money money'/><category term='coffee'/><category term='watir'/><category term='management'/><category term='ride &apos;em cowboy'/><category term='subversion'/><category term='database'/><title type='text'>48KLoCs of Power</title><subtitle type='html'>From Dark Office -&gt; Great Software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>57</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8943833697688999901</id><published>2009-04-15T18:47:00.001-07:00</published><updated>2009-04-15T18:48:33.622-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='i am one of the greatest designers of all time'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>Kudos on unscrewing yourself, MSDN!</title><content type='html'>&lt;p&gt;Seen and heard (but mostly seen) – MSDN’s &lt;s&gt;shiny&lt;/s&gt; skinny new look.&lt;/p&gt; &lt;p&gt;Compare and contrast the two looks.  Here’s a random page about one of the classes you can use to hammer on XML, &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.localname.aspx"&gt;the way it was before&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;And &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.localname%28loband%29.aspx"&gt;here's the new low-bandwidth edition&lt;/a&gt; of the same page.&lt;/p&gt; &lt;p&gt;Oh hey look – I don’t have to dig through panes and curse quietly to myself when that fucking clownishly giant left pane class navigator slides in and out because I’m using Firefox’s incremental search-as-you-type or target where I wants to scroll.&lt;/p&gt; &lt;p&gt;The garnish disappears quickly and I’m left chewing on the meat of the information that I wanted to get at.&lt;/p&gt; &lt;p&gt;Executive summary – dear designers, please consider servicing the needs of your users rather than merely servicing yourself.&lt;/p&gt; &lt;p&gt;Love, me.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8943833697688999901?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8943833697688999901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8943833697688999901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8943833697688999901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8943833697688999901'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2009/04/kudos-on-unscrewing-yourself-msdn.html' title='Kudos on unscrewing yourself, MSDN!'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-9009482820495826961</id><published>2008-11-27T12:12:00.001-08:00</published><updated>2008-11-27T12:16:10.014-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='w3c is not people'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>W3C - A Decade+ of Fail</title><content type='html'>&lt;p&gt;Back in the wild days of the early web, it was pretty clear that someone needed to get their shit together and tell people how it was and how it should be.  Everyone had their strange little additions to HTML to twist and turn it different ways, and there was no clear delineation between right and wrong.  Are tables OK?  Are frames?  What about iframes?&lt;/p&gt; &lt;p&gt;Thankfully, the W3C was there to clear things up and make sure that there was a clear path between right and wrong.&lt;/p&gt; &lt;p&gt;Thanks to the magnificent stewardship of the W3C, we've seen &lt;a href="http://www.w3.org/Amaya/"&gt;reference browsers&lt;/a&gt; so that it's clear how web pages should look.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Just think - if it weren't for the W3C, we'd be stuck with goofy tags like &lt;blink&gt;blink&lt;/blink&gt; and marquee that were added in by Netscape and Microsoft respectively to this day!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;marquee&gt;That'd be terrible!&lt;/marquee&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Thank god they locked that shit down and slapped people's hands when they tried to add inane crap like that in, right?&lt;/p&gt; &lt;p&gt;Except, judging by the fact that you're blinking and rubbing your eyes and probably cursing me for being such a dick and stuffing those two proprietary tags in there and your browser rendering them, they failed.&lt;/p&gt; &lt;p&gt;CSS was put out with the best of intentions, but when it comes to CSS, you can count on one thing - it will not work right the first time in all browsers.  Ever.&lt;/p&gt; &lt;p&gt;Which doesn't stop them from diving ever deeper into never-never land and releasing specs on how to generate tables using nothing but &lt;a href="http://www.w3.org/TR/css3-layout/"&gt;CSS and magic&lt;/a&gt; to the public.  Not that CSS1's all that well-supported.  Or CSS2.  But don't worry, just use CSS3 and suddenly everything gonna be OK!  Oh, if only we had some way to express tabular data that's supported in all browsers.  &lt;a href="http://werbach.com/barebones/barebones.html#tables"&gt;If only&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The simple use cases don't work right but it doesn't stop them from putting out ever more elaborate specs based deeper and deeper in fantasy land.  Worse yet, you'll find supporters who say things like...&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The difference is that an HTML table is semantic (it describes the data). The 'table' value of the display: property has no semantic meaning, and simply tells the browser how to display something. There is a huge difference there.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You dare to question the sanity of an elaborate hand-waving solution that doesn't work in, oh say, 25% of browsers out there when there's a simple way that works reliably?&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;It's only silly if you refuse to distinguish between content and layout.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In a sense, this is correct.  Of course, this is in the same sense as me saying "I can go ahead and chop my legs off because it's silly to walk when jetpacks and rocket cars are obviously the way of the future."&lt;/p&gt; &lt;p&gt;I will give the W3C credit - I didn't know that there was a terser abbreviation for &lt;a href="http://c2.com/xp/YouArentGonnaNeedIt.html"&gt;You Aren't Gonna Need It&lt;/a&gt; than YAGNI, but it looks like "W3C" will do.&lt;/p&gt; &lt;p&gt;So why a decade+ of fail?  They did start &lt;a href="http://www.w3.org/TR/WD-xml-961114"&gt;churning out the XML spec back in 1996&lt;/a&gt;, and they managed to not fuck that up too badly (probably despite their best efforts).  I know, LISP people - XML is a mangled version of sexprs.  I have no idea what that means, but I will nod and slowly back away.  I know, internet.  XML is the worst format ever invented.  Angle bracket tax!  Excessively verbose!  Have you seen the stupid things that people have done with it?  Why didn't we settle on JSON or YAML?&lt;/p&gt; &lt;p&gt;But you know what?  I can produce XML here and have confidence that whoever I hand it to is going to be able to do something meaningful with it.  It's readily (if not speedily) parsed on just about every platform out there.  For a lowest common denominator intercommunication, I gotta admit - it doesn't suck much worse than any other option available.&lt;/p&gt; &lt;p&gt;That doesn't excuse the W3C from strapping on the &lt;a href="http://thedailywtf.com/Articles/The_Complicator_0x27_s_Gloves.aspx"&gt;complicator's gloves&lt;/a&gt; and trying to make it do things that it utterly fails at.  &lt;a href="http://www.w3.org/TR/soap/"&gt;SOAP&lt;/a&gt;?  OK in theory, but were they not aware that interchange was going to be happening over public networks and maybe encryption was something that should be built into the messaging by default?  Violate the spec and you've got what you want.  Was there a point to the spec in the first place?&lt;/p&gt; &lt;p&gt;Oh and did I mention that you can count on SOAP calls across heterogenous clients to be a massive pain in the balls?  When we started on our new project, calling across the wire to a service written in Java, we had two options - XML using their little format or SOAP.  I put my foot down on using XML and refused to say more than "the only benefit to using SOAP will be hearing me laugh a lot at whoever has to implement it, because I won't even try it."  I didn't even need to drop a "told you so" when our SOAP services started failing for no particularly good reason other than it was written in WCF and the consumer had the temerity to be written in .Net 2.0.&lt;/p&gt; &lt;p&gt;And &lt;a href="http://www.w3.org/2001/03/WSWS-popa/paper23/"&gt;SAML&lt;/a&gt;?  Godawful.  Over-wrought.  A solution in search of a problem.  A magnificently high face-to-palm ratio.  I brushed up against that turd once upon a time and I can still taste the bile in the back of my throat because of it.  For that one alone I would like to firebomb the collective crotches of the W3C's membership.&lt;/p&gt; &lt;p&gt;But they keep on trucking and suckers keep slurping it up.&lt;/p&gt; &lt;p&gt;I'm a caveman and a terrible designer and I write pages using tables instead of divs.  On the bright side, I don't spend days lost in trying to figure out why float isn't working in IE6 when it is in Firefox and now it's working in IE6 and Firefox and not IE7 and... who else is up for a trip over to W3C headquarters to visit unimaginable horrors on their collective genitalia?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-9009482820495826961?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/9009482820495826961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=9009482820495826961' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/9009482820495826961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/9009482820495826961'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/11/w3c-decade-of-fail.html' title='W3C - A Decade+ of Fail'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4101972360882558389</id><published>2008-07-29T21:04:00.000-07:00</published><updated>2008-07-29T21:04:00.223-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Tripping into the valley of fail</title><content type='html'>&lt;p&gt;C# 2.0 introduced &lt;a href="http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx"&gt;nullable types&lt;/a&gt; to the language (apparently &lt;a href="http://blogs.msdn.com/ericgu/archive/2004/05/27/143221.aspx"&gt;late in the dev cycle&lt;/a&gt; - more on that soon), something that I could have used way back when.&lt;/p&gt; &lt;p&gt;I know, LtU duders - &lt;a href="http://lambda-the-ultimate.org/node/2699"&gt;nobody can prove that we really need null&lt;/a&gt; and it's a terrible idea.  Or an OK enough idea in the absence of rigorous mathematical proofs but, and don't let nobody in on this, I nearly flunked out of my 9th grade math class (which was really the advanced 10th grade math class; I can't explain it neither) because &lt;strong&gt;I could not prove my way out of a paper bag&lt;/strong&gt;.  Calculus eluded me and vector math haunts my nightmares.  I'm no math pro and this is a blind spot I'm all too aware of.&lt;/p&gt; &lt;p&gt;But null's really useful, honest.&lt;/p&gt; &lt;p&gt;In our application, we have to deal with dates that the user's supplying.  Since this is client-side input, we have to deal with two possible fundamental problems with the dates.  Did they forget to enter a (mandatory) date?  Did they enter an invalid date?&lt;/p&gt; &lt;p&gt;I mention dates because they're (in .Net) a value type.  Like other value types, once you create the variable, they're automatically assigned a value as opposed to reference types, which are null until you instantiate them (the pointer, she points nowhere).  And then there's string, which lives in a state of sin in the gray area between value and reference (it's a reference type but when you pass/copy it, you get a copy of the string rather than a pointer to the object).  Officially, a string's an "immutable reference type" (thanks, Google!).  Tangentially, are there other immutable reference types in the .Net framework?  Damned if I can think of one.&lt;/p&gt; &lt;p&gt;So what's any of this have to do with nullable values?&lt;/p&gt; &lt;p&gt;The user forgot to enter a date.  OK.  What value should we use to represent the fact that that the user entered an invalid date?  DateTime.MinValue, maybe?  Sounds reasonable.&lt;/p&gt; &lt;p&gt;That's covered, so on to fundamental bloops number two - the user entered an invalid date.  Hmm.  DateTime.MinValue's already been recycled as a magic number to represent "missing date", so we'll use DateTime.MaxValue.  Game, set, ma... oh, wait.&lt;/p&gt; &lt;p&gt;You mean we'll have a need throughout the application to use DateTime.MaxValue to represent things that are open-ended?&lt;/p&gt;&lt;p&gt;Now we've got a problem.  Do we want to pick out a second magic number to represent the fact that the user entered an invalid date?  Maybe treat an invalid date and a date that hasn't been entered identically?  Maybe we want to wrap dates in a struct that contains a DateTime and booleans for invalid/missing date?&lt;/p&gt; &lt;p&gt;Hmm.  &lt;a href="http://c2.com/xp/CodeSmell.html"&gt;That code's starting to stink pretty badly&lt;/a&gt;.  There's got to be a better way.&lt;/p&gt; &lt;p&gt;That's where I was hoping nullable types would come to the rescue.  Where previously we had to use magic numbers to represent error states in our values, we can now use a not-so-magic value - null.&lt;/p&gt; &lt;p&gt;Suddenly, we're not looking to wrap things in a struct and perform all sorts of acts that no shower will ever quite rinse off.  User forgot to enter a value?  Null.  Invalid date?  DateTime.Minvalue.  &lt;em&gt;Take in the win&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Did I mention that nullable types came late in the development cycle?  Let's take a look at a little code and see how it works out.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;string nullStr = null;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;nullStr.ToString();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Trying to execute a method on an uninitialized variable - what do you get?  A NullReferenceException.  No-brainer.&lt;/p&gt; &lt;p&gt;&lt;code&gt;int? nullInt = null;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;nullInt.ToString();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Let's try the same thing on a nullable integer.  We should get the same thing, right?  Wrong.  It returns string.Empty.  To get the same result, you'd have to say...&lt;/p&gt; &lt;p&gt;&lt;code&gt;int? nullInt = null;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;nullInt.Value.ToString();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;b&gt;What the shit?  Nullable types have a .Value property?&lt;/b&gt;  Pro move, guys.  Way to leak the fuck out of that abstraction.&lt;/p&gt; &lt;p&gt;Truth be told, ToString() not horking a NullReferenceException doesn't bother me that much.  It's the unexpected coalescing of a null value that gets me.  I set out with my &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;golden hammer&lt;/a&gt; to create a new li'l method called ToStringOrNull() and hang it off of Nullable&amp;lt;T&amp;gt; that does what I'd have designed ToString() to do in the first place - return a null string if the value's null and call the generic ToString() function otherwise.  But I can't attach a &lt;a href="http://msdn.microsoft.com/en-us/library/d5x73970%28VS.80%29.aspx"&gt;constraint&lt;/a&gt; to that function because Nullable&amp;lt;T&amp;gt; is a structure, not a class.  Fail, fail again. &lt;/p&gt;&lt;p&gt;Polluting the namespace with this feels wrong, so what do I do? &lt;/p&gt;&lt;p&gt;Tell other developers to always use nullableType.Value.ToString() and hope that nobody slips up?&lt;/p&gt;&lt;p&gt;Add bunches of tests to our increasingly tag soup-y &lt;a href="http://www.asp.net/mvc/"&gt;MVC&lt;/a&gt; app (and hope that nobody forgets to do it)? &lt;/p&gt;&lt;p&gt;Not good times.  Small inconsistencies pile up until you're so busy bookkeeping for them that you can pretty easily lose sight of the bigger picture.  Either that or you grow your Unix beard out and spend your days using your phallus to point to chapter and verse for the reference specification for your language of choice on Usenet.  The latter's not an option for me since I can't grow a beard and the former ain't pretty neither.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I'm hoping that I can sneak in some elegant solution to calm this jittery behavior, but I've got no idea what it'll look like.&lt;/p&gt;&lt;p&gt;I just wanted to give a special shout-out to whoever for the head-scratching behavior.  Wait.  Is the person behind &lt;a href="http://48klocs.blogspot.com/2007/10/debuggerstepthrough-considered-arrogant.html"&gt;[DebuggerStepThrough]&lt;/a&gt; behind this?  By all that is unholy, &lt;span style="font-weight: bold; font-style: italic;"&gt;I will get you for this&lt;/span&gt;.  These.  Whatever.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4101972360882558389?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4101972360882558389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4101972360882558389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4101972360882558389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4101972360882558389'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/07/tripping-into-valley-of-fail.html' title='Tripping into the valley of fail'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7767330394825287086</id><published>2008-07-20T18:08:00.000-07:00</published><updated>2008-07-20T18:43:21.954-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Unit testing - prefer messages</title><content type='html'>&lt;div&gt;tl;dr version - if your unit test tool lets you &lt;a href="http://www.nunit.org/index.php?p=equalityAsserts&amp;amp;r=2.4.7"&gt;associate (informational) messages&lt;/a&gt; with your test assertions, &lt;i&gt;use the fuck out of them&lt;/i&gt;.  It's great that you're driving towards 100% code coverage.  How much greater will it be in 2 months when someone (probably you) breaks a test and has a useful indicator of what exactly was being exercised rather than trying to puzzle out a simple assertion? &lt;/div&gt;I'm sadly new to the unit testing game, so I've been learning the wrong way to do things at an astonishing clip, while mistakenly stumbling over things that work by accident every now and then.&lt;div&gt;I never quite understood the hubbub over unit testing - why do I want to do extra work that doesn't go towards getting a working product out the door?  Now that I'm writing oodles of unit tests, I understand exactly why I want to write them - they save my ass early and often.&lt;/div&gt;&lt;div&gt;Case in point - the object to XML mapper (this isn't &lt;a href="http://c2.com/cgi/wiki?NotInventedHere"&gt;NIHS&lt;/a&gt;; I genuinely can't use &lt;a href="http://msdn.microsoft.com/en-us/library/bb387098.aspx"&gt;LINQ to XML&lt;/a&gt; because the hierarchy the external service produces is not only unpublished but subject to change) I'm writing.  It's been working, but I noticed that it was... how shall I say... less than performant?&lt;/div&gt;&lt;div&gt;So I set out to start refactoring critical sections of the code.  I started by gut - I started taking FxCop up on its suggestion to use IXPathNavigable and knocked bunches of stuffs out.  Minor improvements.&lt;/div&gt;&lt;div&gt;Then I stopped programming by guesswork and profiled a generic run pattern.  Creating objects (with objects creating other objects), updating the persistent XML store, blah blah blah.  Found the genuinely astonishingly slow parts of my code and broke out the chainsaw to fix them up.&lt;/div&gt;&lt;div&gt;For a change, I had a really, really high level of confidence in all the changes that I was making.  Before unit tests, it was just more guesswork as to what I might be breaking outside of the code that I was touching just by looking at it funny and changing this postfix increment to a prefix increment (OK; that's an exaggeration, but you kinda know what I mean).  Now that I've got unit tests in place, it's a whole different story.  I can try things out and &lt;span class="Apple-style-span" style="font-style: italic;"&gt;see if anything breaks in real time&lt;/span&gt;.  If the coverage is good enough, I've got silly confidence that everything's on the up-and-up.  If it isn't, whatever.  Adding a few more tests isn't moving mountains.&lt;/div&gt;&lt;div&gt;But a strange thing happened along the way - unit tests that I'd written a month or two earlier started breaking.  Even stranger, I had no idea what some of them were doing.  Not many of them, but I was clueless about the provenance of some of the tests that I'd written a couple of months earlier.&lt;/div&gt;&lt;div&gt;That sends up red flags for me - there's still value in having those unit tests, but I can recognize that if I don't have a little more context associated with them, they're going to bit rot really, really fast.  I started by putting comments above the tests explaining what they were doing, but that felt kind of unsatisfying.&lt;/div&gt;&lt;div&gt;Then I &lt;a href="http://www.nunit.org/index.php?p=equalityAsserts&amp;amp;r=2.4.7"&gt;cracked open the manual and discovered that you can attach messages with your assertions&lt;/a&gt;.  Epic win.&lt;/div&gt;&lt;div&gt;I find that when I write unit tests, I slip into a lightweight QA state of mind - I think less about the cases that should work and more about the edge cases, the awkward states that I can put my code into to get it to break.  It gives me a chance to stand back and re-examine the code from that stance as well as getting a feel for how easy the class is to use, since I have to instantiate objects (and everything else in its dependency graph) before I can start to test it.&lt;/div&gt;&lt;div&gt;The time that I'm thinking about what the class is doing for me and how to use it lends itself naturally to embedding context in the tests.  Not simple messages like "validating that CountryCode gets populated when the object's hydrated from XML" but "validating that nullable enumerations are being populated properly."&lt;/div&gt;&lt;div&gt;Prefer messages in the unit tests you write.  They'll help you make the most out of your unit tests as you write them and they'll help you understand your unit tests when they break down the road.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7767330394825287086?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7767330394825287086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7767330394825287086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7767330394825287086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7767330394825287086'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/07/unit-testing-prefer-messages.html' title='Unit testing - prefer messages'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-759220461467851005</id><published>2008-07-13T22:38:00.001-07:00</published><updated>2008-07-13T22:39:42.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Mea culpa</title><content type='html'>&lt;p&gt;When I first started writing .Net code, I was all about implementing IDisposable because I figured that the GC wouldn't be as smart, as fast, as efficient as the stuff I could write.  I mean, sure - they optimize for the general case, but who knows better than I do &lt;em&gt;just when to free memory and resources&lt;/em&gt;?  Not some jackhole Microsoft programmer, amiritepeople?&lt;/p&gt; &lt;p&gt;Since those were the heady days of VC and no clients demanding things change yesterday, I actually spent half a day working with the clumsy spike I'd slapped together and let it fly - it worked well enough under load, so I was happy.  Then I ripped out my destructor and let it roll again - I was figuring I'd see the CPU thrashing as .Net's garbage collector did its thing, working on the general, sub-optimal, case it was written for.  No egghead knows better than I do how and when this should run!&lt;/p&gt; &lt;p&gt;Except that there was no difference that I could see.  If anything, run time was a little faster and memory overhead was a little lower.  I mean, probably statistical noise faster and lower (that Excel spreadsheet's been lost to the river of time at this point), but that was a pretty well-defined zenslap moment for me.&lt;/p&gt; &lt;p&gt;I thought about it a little and realized that oh yeah - that garbage collector.  I'm not allocating memory either.  People way smarter than me have already implemented a garbage collector so I don't have to worry about allocating and freeing memory on the fly.  The bold promise of distilling your codebase down to actual business logic rather than bookkeeping allocations and all that.&lt;/p&gt; &lt;p&gt;It's a solved problem, so why am I solving it again, only invariably worse this time?  Maybe it was written for a "general case" (whatever the fuck that means because I obviously can't defend it) but it was a &lt;strong&gt;pretty good general case&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;This all came flooding back to me on Friday.  I'm working on a bit of code - an object-XML mapper.  This isn't as stupid as it sounds (I hope), honest.  It's running, well.  Not so good.  I mean, it does what I want it to, just way way way slower than I want it to run.&lt;/p&gt; &lt;p&gt;One of the "optimizations" I made was ripping out a &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;lambda expression&lt;/a&gt; iterating over a singleton (I know, I know) - I figured that there ain't nothing faster than a hand-rolled for loop with a break condition... right?  But I wasn't making any headway with the other two offending methods after re-ordering my if block, so I decided that I might as well, you know, test it out to see how it performed.&lt;/p&gt; &lt;p&gt;I didn't check memory this time around, but damn if it wasn't just as fast as the for loop.  Maybe a little faster, even.&lt;/p&gt; &lt;p&gt;Again, the zenslap - the framework's made by people way smarter than I am.  I need to count on them to have done their homework and made stuff easy to use and &lt;em&gt;scary fast&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?NotInventedHere"&gt;Stop reinventing the wheel&lt;/a&gt;.  I'd bark at co-workers who tried to roll their own second-rate mechanism for mapping objects to an XML hierarchy we don't control, so why am I confident in my ability to roll my own iteration loop?  On some level, doesn't it make sense that smart people who get paid to work on iterators might find a way to wring a little more out of them?&lt;/p&gt; &lt;p&gt;It's not easy discovering that something so simple that you've taken for granted for so long (a for loop!!!) is halfway obsolete, but it's liberating once you get over yourself and embrace it.&lt;/p&gt; &lt;p&gt;So here's to you, whoever implemented .Any() - you did a helluva job.  Way better than the jackass who shat out &lt;a href="http://48klocs.blogspot.com/2007/10/debuggerstepthrough-considered-arrogant.html"&gt;[DebuggerStepThrough]&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-759220461467851005?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/759220461467851005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=759220461467851005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/759220461467851005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/759220461467851005'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/07/mea-culpa.html' title='Mea culpa'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6211070530283256320</id><published>2008-06-24T22:53:00.000-07:00</published><updated>2008-06-24T23:11:26.747-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Software management - The Oregon Trail model</title><content type='html'>&lt;p&gt;OK, forget reading Peopleware and The Mythical Man-Month.  If you want to manage developers, there's only one - no wait! - two things you need to do.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Be born in the late 70's/early 80's  &lt;/li&gt;&lt;li&gt;Play &lt;a href="http://en.wikipedia.org/wiki/The_Oregon_Trail_%28computer_game%29"&gt;The Oregon Trail&lt;/a&gt; on an Apple II&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;That's it!  If you can make it to the end of the trail, you know everything that you need to know about successfully managing software, so go successfully manage the shit out of a project or three!&lt;/p&gt; &lt;p&gt;Wait.  You're still here?  I should go on?  OK.&lt;/p&gt; &lt;p&gt;You have your hunters, guys who strike out in hopes of lucking into a bounty of delicious, delicious meat.  Speaking authoritatively as someone who's never hunted or caught anything of note while fishing, I'll say that a good hunter operates off of instinct, innate ("animal") intelligence, skill and luck.  Legends tell the tale of the hunter who struck off into the deep of the jungle with nothing but a knife and came back carrying a gorilcopterous (work with me people, I live on the edge of the tundra) or some big tasty animal that lives in the jungle&lt;sup&gt;0&lt;/sup&gt;.&lt;/p&gt; &lt;p&gt;Then you've got the gatherers who plant crops and (hopefully) eventually got to harvest the bounty.  It takes a deep investment in time and resources to see a field from seed to harvest, and even then there's any number of natural disasters that can beset you along the way.  This isn't to say it's easy.  On some level, we all understand how plants grow.  They eat sunshine, water and carbon dioxide and crap oxygen and chlorophyll, right?  On another level, there's a hell of a lot that goes into it - seeds cost money.  Machines to till and harvest cost money.  Irrigation costs money.  You've got to know when to plant.  What to plant.  When to rotate your crops.&lt;/p&gt; &lt;p&gt;Developers are an impatient bunch, which means that we don't generally have the patience for the small, far-off, rewards and repetitive work that it takes to grow a crop.  But we get hungry, so we're going to strike out and hunt, hoping to bag the next seminal idea.  OK, it's probably not a seminal idea by any stretch of the imagination, but for a brief moment in time, you really feel like you've crafted something brilliant and have found something more than you could have hoped for, something that's somehow bigger than you could have imagined.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/dave.c.solomon/SGGzIHXL7_I/AAAAAAAAAFg/Zw2ba2pFD38/s1600-h/cup%20overfloweth%5B4%5D.png"&gt;&lt;img style="border-width: 0px;" alt="cup overfloweth" src="http://lh3.ggpht.com/dave.c.solomon/SGGzIUPUTwI/AAAAAAAAAFk/GZIsZAJ1VMc/cup%20overfloweth_thumb%5B4%5D.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;But eventually, the quarry of the once-fertile plains and forests &lt;em&gt;of imagination!!!!!!!&lt;/em&gt; will run dry.  Your hunters will pick up on the fact that there's no more ideas to be hunted, only tedious fields that demand regular, monotonous maintenance, and they'll migrate elsewhere.  This is all well and good, but every now and then wouldn't you like a steak to go with those potatoes?&lt;/p&gt; &lt;p&gt;But again, I get ahead of myself - let's take a step back to see what a dated educational game has to do with any of this.&lt;/p&gt; &lt;p&gt;In The Oregon Trail, you're in charge of seeing a family&lt;sup&gt;1&lt;/sup&gt; make the trip on the Oregon Trail from Missouri&lt;sup&gt;2&lt;/sup&gt; to Oregon&lt;sup&gt;3&lt;/sup&gt;.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/dave.c.solomon/SGGzIpdjLaI/AAAAAAAAAFo/QhpL8M8jABQ/s1600-h/overview%5B1%5D.png"&gt;&lt;img style="border-width: 0px;" alt="overview" src="http://lh6.ggpht.com/dave.c.solomon/SGGzI_L5zCI/AAAAAAAAAFs/aVykSxdnlVo/overview_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p align="left"&gt;You notice how they emphasize "try"?  It's because of a simple fact that you don't want to admit to yourself - &lt;em&gt;&lt;a href="http://forums.construx.com/blogs/stevemcc/archive/2008/05/13/Software_2700_s-Classic-Mistakes_2D002D00_2008.aspx"&gt;no matter how simple it seems like it should be, that shit is fucking hard to accomplish&lt;/a&gt;&lt;/em&gt;&lt;sup&gt;4&lt;/sup&gt;.  To the outsider, it's as simple as getting from point A to point B.  That's really all there is to it, right?&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/dave.c.solomon/SGGzJEBvgwI/AAAAAAAAAFw/O8owevKOmfo/s1600-h/when%20to%20leave.png"&gt;&lt;img style="border-width: 0px;" alt="when to leave" src="http://lh5.ggpht.com/dave.c.solomon/SGGzJtEpT7I/AAAAAAAAAF4/80YQklmc-ac/when%20to%20leave_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="left"&gt;Go figure - there's nuances that you hadn't even considered when you started out.  Could this mean that you'll eventually discover that there are nuances upon nuances?  This makes the decision of something that seems as simple as when to leave a dizzyingly difficult one.&lt;/p&gt; &lt;p align="left"&gt;Leave early and you'll be freezing and making slow, painful, progress&lt;sup&gt;5&lt;/sup&gt;.  Leave too late and you'll face the unenviable, super-difficult, task of over-wintering&lt;sup&gt;6&lt;/sup&gt;.  Face it - you've tried to make a trip like this before and you've probably still got the bruises and scars from the last one, but you keep telling yourself that &lt;strong&gt;this time will be better&lt;/strong&gt;.&lt;/p&gt; &lt;p align="center"&gt; &lt;a href="http://lh6.ggpht.com/dave.c.solomon/SGGzJ16F5DI/AAAAAAAAAF8/-3RYQVOUClQ/s1600-h/intro%5B1%5D.png"&gt;&lt;img style="border-width: 0px;" alt="intro" src="http://lh3.ggpht.com/dave.c.solomon/SGGzKL1lHwI/AAAAAAAAAGA/4-T2ZiaaWag/intro_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="left"&gt;You need supplies to make the trip.  Oxen to move your cart&lt;sup&gt;7&lt;/sup&gt;, clothing to keep you warm&lt;sup&gt;8&lt;/sup&gt;, food&lt;sup&gt;9&lt;/sup&gt;, replacement parts&lt;sup&gt;10&lt;/sup&gt;... and bullets for hunting&lt;sup&gt;11&lt;/sup&gt;.  And naturally, you're constrained to a budget that's tighter than you'd like.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/dave.c.solomon/SGGzKZ5tkmI/AAAAAAAAAGE/8F6-QsqMpRE/s1600-h/store%5B1%5D.png"&gt;&lt;img style="border-width: 0px;" alt="store" src="http://lh3.ggpht.com/dave.c.solomon/SGGzKnuPquI/AAAAAAAAAGI/jEV-5YNHwIQ/store_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p align="left"&gt;Making matters worse (you mean it gets worse?), you're probably making the trip with a bunch of egomaniacal (wo)man-children.  I mean, we all strive to be &lt;a href="http://www.codinghorror.com/blog/archives/000586.html"&gt;egoless in our tasks&lt;/a&gt;, but we all take an undue amount of pride in an elegant solution and invariably take it the wrong way when someone points out the glaring flaws in our implementation.  Or maybe I'm the only one, who knows?&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/dave.c.solomon/SGGzK1KGA_I/AAAAAAAAAGM/02qjsoNPFrM/s1600-h/ego%5B4%5D.png"&gt;&lt;img style="border-width: 0px;" alt="ego" src="http://lh4.ggpht.com/dave.c.solomon/SGGzLIACVwI/AAAAAAAAAGQ/X6sEMzYN1QI/ego_thumb%5B3%5D.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;But... about those supplies.  Some of them are effectively interchangable.  If you've got a good hunter (you have a good hunter, right?), you can exchange bullets for food in the wild - that's the biggest bang (pun unintended) for your buck.  Then you can trade food for just about anything else you need along the way&lt;sup&gt;12&lt;/sup&gt;. You can run pretty lean-and-mean&lt;sup&gt;13&lt;/sup&gt; but you need enough food to keep your bellies full.&lt;/p&gt; &lt;p&gt;You're going to want to hunt (because it's &lt;strong&gt;fun!&lt;/strong&gt;), but not every hunt can be a winner.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/dave.c.solomon/SGGzLUm-oUI/AAAAAAAAAGU/uYbFMPdHh_w/s1600-h/hunting%20is%20tough.png"&gt;&lt;img style="border-width: 0px;" alt="hunting is tough" src="http://lh4.ggpht.com/dave.c.solomon/SGGzLn0UCQI/AAAAAAAAAGY/mRevSwERCZE/hunting%20is%20tough_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;What can I tell you?  Times is tough out there.  Even with a gang of elite hunters firing on all cylinders and a pile of food (&lt;strong&gt;ideas!&lt;/strong&gt;) as high as the eye can see, sometimes nature just doesn't smile on you.  As in any pursuit, it's entirely seemly that you can do everything right and still fail.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/dave.c.solomon/SGGzL6TSs8I/AAAAAAAAAGc/U9wP0pYGvMQ/s1600-h/times%20is%20tough.png"&gt;&lt;img style="border-width: 0px;" alt="times is tough" src="http://lh4.ggpht.com/dave.c.solomon/SGGzMZ19jwI/AAAAAAAAAGg/TAZFJXjBAfY/times%20is%20tough_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Not only are times tough as hell, but you're fairly constantly reminded of your own failures and the failures of others in a big, somber way.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/dave.c.solomon/SGGzMjJwaYI/AAAAAAAAAGk/OVZgzIen1cc/s1600-h/einstein%27s%20grave.png"&gt;&lt;img style="border-width: 0px;" alt="einstein's grave" src="http://lh5.ggpht.com/dave.c.solomon/SGGzMxuoG8I/AAAAAAAAAGo/s2rVflBuKhs/einstein%27s%20grave_thumb.png?imgmax=800" border="0" height="278" width="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Is there any wonder why Einstein up there didn't make it?  Wasn't cut out for it.  You &lt;a href="http://www.hanselman.com/blog/YouCantTeachHeightMeasuringProgrammerCompetenceViaFizzBuzz.aspx"&gt;can't teach people how to hunt&lt;/a&gt; - they're born with it or they'll never get it, now matter how blue in the face you get trying to explain it to them.&lt;/p&gt; &lt;p&gt;The trip itself?  It's possible that your people are entirely happy in Missouri right now.  You can crack that whip all they want, but if you don't &lt;a href="http://weblog.raganwald.com/2007/11/vast-and-endless-sea.html"&gt;instill a powerful longing in them&lt;/a&gt; to reach the promised land of Oregon, you'll never make it.  In fact, you might find yourself unwillingly invited to a &lt;a href="http://en.wikipedia.org/wiki/Donner_Party"&gt;Donner Party&lt;/a&gt;.  And not to ruin the surprise, but everyone at the party will be eating but you.&lt;/p&gt; &lt;hr noshade="noshade"&gt; &lt;small&gt; &lt;/small&gt;&lt;p&gt;&lt;small&gt;0. you know, your run-of-the-mill whispered about in legends superhacker&lt;br /&gt;1. your development team&lt;br /&gt;2. the start of the project&lt;br /&gt;3. the project's end (you do have a concrete end-point in mind, right?)&lt;br /&gt;4. #9 on Software's Classic Mistakes - Wishful Thinking&lt;br /&gt;5. sometimes you have the toolchain you need to complete your project, other times you're kind of winging it as you go along - bootstrapping too much of your own technology stack only shrinks the chances that you'll ever make it&lt;br /&gt;6. running out of funding&lt;br /&gt;7. computers&lt;br /&gt;8. technology stack - compiler, language, yadda yadda&lt;br /&gt;9. ideas&lt;br /&gt;10. source control and the other niceties of modern development (build server, unit tests)&lt;br /&gt;11. ain't nothing more dire than running out of bullets - there's no metaphor here&lt;br /&gt;12. dumbest way of describing the point of open source ever?&lt;br /&gt;13. agile??!?&lt;/small&gt;&lt;/p&gt;&lt;small&gt;  &lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6211070530283256320?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6211070530283256320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6211070530283256320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6211070530283256320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6211070530283256320'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/06/software-management-oregon-trail-model.html' title='Software management - The Oregon Trail model'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/dave.c.solomon/SGGzIUPUTwI/AAAAAAAAAFk/GZIsZAJ1VMc/s72-c/cup%20overfloweth_thumb%5B4%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4522486260059388053</id><published>2008-06-21T23:26:00.000-07:00</published><updated>2008-06-21T23:26:00.467-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>This week's dispatch from the seventh circle</title><content type='html'>&lt;p&gt;"I don't understand why &lt;a href="http://blogs.msdn.com/fxcop/"&gt;FxCop&lt;/a&gt; is complaining about this static property on a static class."&lt;/p&gt; &lt;p&gt;"Probably because static classes are stateless, so exposing properties doesn't make a whole lot of sense."&lt;/p&gt; &lt;p&gt;"Yeah, but I want to expose properties so that a caller can set the values that they want."&lt;/p&gt; &lt;p&gt;"But that's really not such a great idea.  Either overload methods with the parameters you're trying to read from properties or let callers instantiate the class and set the properties themselves."&lt;/p&gt; &lt;p&gt;Why did I &lt;a href="http://www.noop.nl/2008/04/the-perfect-job.html"&gt;find this so disturbing&lt;/a&gt;?  Probably because it took two days for the chap to make the change.&lt;/p&gt; &lt;p&gt;The other reason I found it disturbing?  I did the math in my head and decided that there would be approximately zero point in trying to get him to understand why globally mutable state can quickly lead to misery (false negatives/positives) when you're dealing with the MTA that &lt;a href="http://www.nunit.org/index.php"&gt;NUnit&lt;/a&gt; runs in.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4522486260059388053?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4522486260059388053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4522486260059388053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4522486260059388053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4522486260059388053'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/06/this-week-dispatch-from-seventh-circle.html' title='This week&amp;#39;s dispatch from the seventh circle'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4061300842283673454</id><published>2008-06-17T22:30:00.000-07:00</published><updated>2008-06-17T22:30:01.497-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>Design patterns as religion</title><content type='html'>&lt;p&gt;I've come to an understanding of and guarded appreciation for design patterns.&lt;/p&gt; &lt;p&gt;They're not at all useful in and of themselves, but they are useful at a level of abstraction - they give us a common language to explain our implementations with ("...so basically, the model objects are just kind of &lt;a href="http://msdn.microsoft.com/en-us/library/ah19swz4%28VS.71%29.aspx"&gt;structs&lt;/a&gt; and we cajole them into doing interesting things by &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;Decorating&lt;/a&gt; them...") and, more importantly, they let us learn about the boundaries, limitations and realities of the design space that we're working in by revealing the problems that get solved and solved again and again and... you get the picture.&lt;/p&gt; &lt;p&gt;If your objects start to look like a pattern, it's a curiosity.  Patterns were discovered "in the wild" to begin with, so don't tire your arm out patting yourself on the back for rediscovering one.  No gold star for knocking out a Flyweight, sorry.  On the flip side, don't flagellate yourself when you realize that you've implemented a &lt;a href="http://c2.com/cgi/wiki?SingletonsAreEvil"&gt;Singleton&lt;/a&gt; - if it emerges from solid design, why would you throw it away?&lt;/p&gt; &lt;p&gt;It doesn't matter if you're blindly implementing a pattern or blindly rejecting an implementation because it looks like a pattern that someone on the Internets doesn't like - it's &lt;a href="http://en.wikipedia.org/wiki/Cargo_cult_programming"&gt;cargo cult programming&lt;/a&gt; either way.&lt;/p&gt; &lt;p&gt;Design patterns are there and were there before anyone started looking for them or writing about them.  People have &lt;a href="http://blog.plover.com/prog/design-patterns.html"&gt;classified subroutines as a design pattern&lt;/a&gt; - like other "patterns", this isn't a reason to use or not use them, it's further establishing where they come from - introspection on how we make programs work.  There's something to be said for taking a stroll through that meta-field, but I don't linger there too long.  Most of the time.&lt;/p&gt; &lt;p&gt;All this is a long-winded way of explaining why my monocole absolutely popped out the other day at work.  I was busy doing something or other at the time (transliterating objects to an XML format I don't control using unhealthy amounts of &lt;a href="http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx"&gt;Reflection&lt;/a&gt;, I think?) when I saw one of the other developers explaining something or other.  I popped out my earphones to catch the explanation midway through.&lt;/p&gt; &lt;p&gt;He had the &lt;a href="http://www.amazon.com/Head-First-Design-Patterns/dp/0596007124"&gt;Head First Design Patterns&lt;/a&gt; book open on his desk and was walking through his ideas.&lt;/p&gt; &lt;p&gt;"Why are we bothering with inheritance?  The domain model you guys put together is too convoluted and doesn't work in this case."&lt;/p&gt; &lt;p&gt;"If there's something we missed, it's not like it's set in stone.  If it's really hairy, we can walk through it and see if there's some reasonable way to get it factored in and if there isn't, we can go further back and see how we can make the model work for us."&lt;/p&gt; &lt;p&gt;"The &amp;lt;I forgot already!&amp;gt; pattern says that you can use hashtables to store the data for your objects, rather than inheriting from a base class."&lt;/p&gt; &lt;p&gt;"Well, yeah.  But think about why we use objects and I think you'll see why that's probably a bad idea."&lt;/p&gt; &lt;p&gt;...&lt;/p&gt; &lt;p&gt;"For our model objects, we're use them not only to encapsulate associated data but to make it easily discoverable - when you're working with them internally, it may seem pretty convoluted that your parent base Foo class has property Bar that's exposed by a child Buz object (which has more properties and methods from the IBaz interface that Foo implements), but that's all readily discoverable by anyone who's consuming a Buz object.  They could kind of care less how it works, they just need access to have access to its state and be able to send it messages to have it do interesting things."&lt;/p&gt; &lt;p&gt;He was not sold by my explanation and the discussion closed in on arguing (something about our respective tones and the other developers in the office getting quiet and looking uncomfortable) about whether it makes more sense to have the classes representing data internally like a struct or as a hashtable - I scoffed (and still scoff!) at the idea but told him that he was the one implementing it, so if he had a good reason for properties exposing a hashtable behind the scenes, I was fine with it.&lt;/p&gt; &lt;p&gt;I started to look up hashtables and figure out whether he was really on to something or whether my gut feeling that it was adding an unnecessary level of complexity to the design (OK, I was premature optimizing in my head and wondering about the relative weight of sparsely-populated hashtables, too) when, a few minutes and pages in the book later, he announced to another developer in the office (!!!) that the book said that you should only use hashtables when you're dealing with a lot of inheritance and a lot of properties.&lt;/p&gt; &lt;p&gt;I don't think there was any amount of selling I could have done to get him to walk away from the curious implementation - it was design pattern as dogma.  Blinders on, reject facts, implement on faith and The Pattern will see you through.&lt;/p&gt; &lt;p&gt;I'm still trying to figure out if I was wrong (probably, yeah) for knee-jerking away the use of hashtables or not.  I'll let you know when I turn that page.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4061300842283673454?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4061300842283673454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4061300842283673454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4061300842283673454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4061300842283673454'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/06/design-patterns-as-religion.html' title='Design patterns as religion'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8030128250777312300</id><published>2008-05-29T20:29:00.000-07:00</published><updated>2008-05-29T20:29:01.588-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><title type='text'>Aging codebases, a postscript</title><content type='html'>&lt;p&gt;&lt;a href="http://48klocs.blogspot.com/2008/04/can-codebases-gracefully-age.html"&gt;Ron Avitzur's comment on my post&lt;/a&gt; wondering aloud as to whether code can age gracefully done tickled my brain.  I mean, I think about code a lot.  I think about software and making software a lot.&lt;/p&gt; &lt;p&gt;But for some reason, I hadn't ever pondered how truly strange software is - if you look at it a certain way,  it's never truly broken.  It may be old, it may be ungainly, but it will always do something.&lt;/p&gt; &lt;p&gt;Sure, the hardware that it ran on may disappear or cease to function and the compilers may evaporate... but that doesn't mean that the code's broken.  It just means that you've got a little work ahead of you porting that software to the latest and greatest hardware and toolchain and bingo bango your software's back from the dead.&lt;/p&gt; &lt;p&gt;Of course, there's always the question of "should we?".  Times move on and inevitably reach a tipping point where maybe it makes sense to let that sleeping codebase lie.&lt;/p&gt;&lt;p&gt;Steve McConnell refers to this as a "&lt;a href="http://www.stevemcconnell.com/articles/art03.htm"&gt;doghouse problem&lt;/a&gt;" - when it comes to building a doghouse, everyone has an opinion on what color to paint it, what the roofing tiles should be, the exact dimensions, yadda yadda because it's a problem so eminently tractable that we can easily wrap our heads around it.  Hell, it's within the realm of reason that we could build it ourselves.  We have a pretty good idea of what it'll cost to make and how long it'll take.&lt;/p&gt;&lt;p&gt;But ask us to price the cost, materials, resources and time required to build a skyscraper and... good luck on estimating that one.  How hard can it really be though?  They're both buildings, right?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;A couple of real-world buildings brought this into clear focus for me.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;First is an old mill building not too far from where I live.  For the years I've been here, it's been uninhabited - a hulking, crumbling mess of a building.  100 years ago, I'm sure it was a bustling center of commerce, an economic powerhouse.  Now it's gone past creepy and into sad.  It's being demolished to make way for... I don't know.  Probably another drug store or something.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a border="0" href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5205947192835816962"&gt;&lt;img src="http://lh6.ggpht.com/dave.c.solomon/SD89Y7xrvgI/AAAAAAAAAFQ/PJzJwjaL-tE/s400/crumbling%20mill%20building.jpg" /&gt;&lt;br /&gt;(zoom on the crumble)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Second is This Old House, or what's left of it.  There was a house there once, nothing here now but the bones of the old building rising like so many dinosaur bones from the ground.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a border="0" href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5205947192835816978"&gt;&lt;img src="http://lh6.ggpht.com/dave.c.solomon/SD89Y7xrvhI/AAAAAAAAAFY/IpZSPt7rKOI/s400/house%20skeleton.jpg" /&gt;&lt;br /&gt;(check them bones)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Either one of them could be broken down as much as possible to be built back up to work again, but it's the house whose bones will remain in place while the mill's ground into the dust.  Looking at it, the possibility of fixing it piecemeal doesn't even enter into your mind - it's over a hundred years old, &lt;b&gt;frigging brick&lt;/b&gt; and huge.  The house, on the other hand?  Over a hundred years old, but the frame and chimney are still sound - we can rebuild around them, putting the walls and stairs and windows in different this time.&lt;/p&gt;&lt;p&gt;When looking at open source projects, it's not uncommon for one of the mentioned features to be their "clean codebase" - on some level, this is kind of laughable because who but a geek gives a shit what the code looks like as long as it runs well enough and does something useful for you?&lt;/p&gt;&lt;p&gt;On another level, it shows that there's people who have taken pride in their work, that &lt;a href="http://en.wikipedia.org/wiki/Fixing_Broken_Windows"&gt;fix broken windows&lt;/a&gt;, and have a vested interest in making sure that a year from now, it will have crumbled less than that mill building.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Think about building something that will stand the test of time and it just might.  Make it concise and useful enough and who knows?   Its framework just might live a decade or so.&lt;/p&gt;&lt;p&gt;I hope to someday build something so good that I won't be able to hear the lamentations of the developers responsible for supporting it because I'm busy watching Wheel of Fortune too loud or whatever it is that incredibly old people do.  Did I mention that I'm watching The Wheel in my rocket car?  Because ideally, I'm incredibly old, reasonably well-to-do and the future finally delivers on its promises.&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;Postscript&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I biked by the house again earlier this week.   Nothing remained.&lt;/p&gt;&lt;p&gt;I still hold out hope for a rocket car-filled future.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8030128250777312300?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8030128250777312300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8030128250777312300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8030128250777312300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8030128250777312300'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/05/aging-codebases-postscript.html' title='Aging codebases, a postscript'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/dave.c.solomon/SD89Y7xrvgI/AAAAAAAAAFQ/PJzJwjaL-tE/s72-c/crumbling%20mill%20building.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6641325382995056339</id><published>2008-05-05T19:53:00.000-07:00</published><updated>2008-05-05T19:53:00.358-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>SQL Server, we need to have a talk</title><content type='html'>&lt;p&gt;So I'm working on normalizing the database the other day.&amp;nbsp; I want to move some columns from a table that I'm about to make vanish to another table and I can't remember the syntax for it.&amp;nbsp; I should have hit up The Google (the SQL syntax for adding tables/columns to tables really is dead simple) but instead I was extra lazy and fired up the table designer inside of SQL Server Management Studio and scripted out the changes to the tables.&lt;/p&gt; &lt;p&gt;I finish that up, finish modifying the stored procedures, everything looks good.&amp;nbsp; I run the SQL script, fire my black box tests against it.&lt;/p&gt; &lt;p&gt;Hmm.&amp;nbsp; Things ain't working right.&amp;nbsp; The column that I just defined to hold a decimal is causing problems.&amp;nbsp; I check my stored procedures to make sure I'm not doing anything insane, check my business logic to make sure I didn't bork anything there, it all looks good.&lt;/p&gt; &lt;p&gt;I take what I'd just scripted and distill it down to its essence.&lt;/p&gt; &lt;p&gt;&lt;pre&gt;create&lt;br /&gt; table scratch&lt;br /&gt; (&lt;br /&gt;   percentage decimal (18,0)&lt;br /&gt; )&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;insert&lt;br /&gt;  into scratch&lt;br /&gt;values (0.5)&lt;br /&gt;&lt;br /&gt;select *&lt;br /&gt;  from scratch&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Not-so-curiously, the scratch table now contains a lone value of 1.0.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;When you look at it, it's obvious what went wrong here - I just defined a decimal with zero digits of decimal precision.&amp;nbsp; Or, as I like to call it, &lt;strong&gt;a fucking integer&lt;/strong&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I obviously biffed in the first place, but this left me scratching my head - why on earth would you make the default for a decimal (effectively) an integer?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As an added bonus head scratcher, there's no warning about the loss of precision/silent rounding when you store the value in there.&amp;nbsp; I don't know what should happen there (do you want an exception because of that sort of thing?) but I do know that it rhymes with "leaky abstraction."&amp;nbsp; I'm not an RDBMS guru, people.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Times like these, I understand why it's regarded as best practice to treat money as two integer values (dollars and cents!) - databases are a bit funky when it comes to storing out your decimal values.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6641325382995056339?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6641325382995056339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6641325382995056339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6641325382995056339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6641325382995056339'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/05/sql-server-we-need-to-have-talk.html' title='SQL Server, we need to have a talk'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1162847885221732148</id><published>2008-04-19T23:30:00.000-07:00</published><updated>2008-04-20T20:43:44.752-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><title type='text'>Can codebases gracefully age?</title><content type='html'>&lt;p&gt;Terrible shame. Monstrous shame.&lt;/p&gt; &lt;p&gt;&lt;a href="http://48klocs.blogspot.com/2008/04/what-does-your-apps-codebase-look-like.html"&gt;I really need to stop looking at my old code&lt;/a&gt;.  More than that, I need my old code to work all the time in the face of needs and requirements that didn't exist when I first wrote it.  Is that even possible?  It isn't when I put it like that.&lt;/p&gt; &lt;p&gt;Probably not. At this point, I'd say "almost certainly not," but it's not like I've seen a whole lot of other projects' codebases (it's not something that I &lt;a href="http://www.hanselman.com/blog/TheWeeklySourceCode24ExtensibilityEditionPlugInsProvidersAttributesAddInsAndModulesInNET.aspx"&gt;do for fun&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;The sad thing is that, not to sound like a monstrously arrogant prick (even though I am), I'm the best developer where I work, by far. When Larry O'Brien made the observation that &lt;a href="http://www.knowing.net/PermaLink,guid,f6755acf-e8df-4f32-8d53-39b9a01992f5.aspx"&gt;bad developers are actively counter-productive&lt;/a&gt;, it riled some people, but &lt;a href="http://48klocs.blogspot.com/2007/06/maggot-therapy-for-code.html"&gt;I'm in complete agreement&lt;/a&gt;. I'm the best developer at my office (sometimes by more than an order of magnitude) and I'm out-and-out embarrassed by code I wrote six months ago. As in "how the fuck did this shit ever work?" embarrassed. As in "if I ever come across a time machine, I'm going back in time to punch myself in the throat for that mess" embarrassed.&lt;/p&gt; &lt;p&gt;And it only gets worse.&lt;/p&gt; &lt;p&gt;This isn't &lt;a href="http://reddit.com/info/6g4aw/comments/c03qvs4"&gt;humility&lt;/a&gt;, this is common sense. Microsoft doesn't want me, Google wouldn't fart in my general direction.  I'm pretty sure even &lt;a href="http://fakesteve.blogspot.com/"&gt;Fake Steve Jobs&lt;/a&gt; would prefer that I not have any Apple products.&lt;/p&gt; &lt;p&gt;I'm certainly no superstar developer (do they really exist in nature?), but even developers way smarter and better than I am have problems with their codebases, especially as they age.&lt;/p&gt; &lt;p&gt;Microsoft's not having such a smooth time of things with Vista - people are &lt;em&gt;hating&lt;/em&gt; it so much that they're apparently &lt;a href="http://thebetaguy.com/exclusives/?postid=1029344029"&gt;seriously thinking about doing away with backwards compatibility&lt;/a&gt;, regarded by some as the albatross around Vista's neck. But... backwards compatibility is what sells Microsoft products for a whole lot of people. Microsoft's got &lt;a href="http://blogs.msdn.com/oldnewthing/"&gt;scary smart dudes&lt;/a&gt; working to insure that your old software will keep working, even if it means that old, really questionable stuff, stays in the OS to keep it working.&lt;/p&gt; &lt;p&gt;They must make bunches of money off of it (there's a school of thought that says that the solid support/backwards compatibility fuels the virtuous cycle that keeps large companies from jumping ship from Microsoft), but with the time overrun and backlash about how assy Vista is, they're thinking about sacrificing a cash cow for a restart on the accretion of bugs they have to support in their codebase.&lt;/p&gt; &lt;p&gt;Apple's another company that's got scary smart dudes working for them. Like, &lt;a href="http://www.pacifict.com/Story/"&gt;even the guys that don't really work for them are scary smart&lt;/a&gt;. Another place where I'm sure I'm the janitors are smarter than I am. Even they've got problems with their codebase.&lt;/p&gt; &lt;p&gt;Even there, when it came time for OS X to come out, they broke backwards compatibility with System 9. There was an emulator or something for it (I could swear my PowerBook has it on it) but they made a clean break of it. With point releases of OS X, they brutally deprecate features and functions, leaving developers to clean up their act or not run in the new version.&lt;/p&gt; &lt;p&gt;It's kind of rough, but it's probably also the right way to go. Yes, as a first course, you want to refactor the hell out of your code.  But they've accepted the fact that their codebase doesn't age gracefully and when they find really objectionable code, they rip it out as soon as they can.  Developers who support Apple apps seem to not mind it all that much (maybe they do?).  As for the users... compare and contrast people's reaction to Leopard and Vista.&lt;/p&gt; &lt;p&gt;I just don't think that it's possible for code to age well.  Bits and pieces may stand the test of time, but the whole will become a not-so-secret shame.  Well, maybe TeX has aged gracefully, but (and no offense intended) &lt;a href="http://www-cs-staff.stanford.edu/%7Euno/address.html"&gt;nobody who's as smart as Donald Knuth&lt;/a&gt; is wasting their time reading this blog.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5191109063850316338"&gt;&lt;img src="http://lh6.ggpht.com/dave.c.solomon/SAqGMJ0b0jI/AAAAAAAAAEw/bRW_HKoglv8/s400/brick%20building%20sign.JPG" /&gt;&lt;br /&gt;(click for more bigger brick)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I think that's a totally lovely sight, but if that were software, a bunch of people (the developers supporting it, the people trying to sell it) would be in a lot of pain because &lt;em&gt;that is unfit&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;I mean, OK.  First it was designed as a brick edifice to hold a building up.  Then someone decided that we could slap an ad for Coca-Cola on it.  Then a real genius figured "hey, it worked for Coke, why not make it work for Gold Medal", and in the process, they lost sight of what it could reasonably support.&lt;/p&gt; &lt;p&gt;If that were software, I'd be scared to touch it - if I do anything with it, I'm going to lose the Gold Medal ad or the Coca-Cola ad or both or the lovely interplay between the two.  I don't want to be responsible for fucking them up.&lt;/p&gt; &lt;p&gt;It only overtly serves one of its intended functions well at this point, when, if it were software, people would be demanding it support all three.  At this point, we can all agree that there are simpler ways to support multiple ads (they're called billboards, have you heard of them?) and maybe we should just strip it back to what it can do well (be a brick wall).&lt;/p&gt; &lt;p&gt;In the face of all this, why do I keep developing?  In the hope that next time I'll get it right.&lt;/p&gt; &lt;p&gt;So what about you out there - do any of you work on applications that only get better with age?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1162847885221732148?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1162847885221732148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1162847885221732148' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1162847885221732148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1162847885221732148'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/04/can-codebases-gracefully-age.html' title='Can codebases gracefully age?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/dave.c.solomon/SAqGMJ0b0jI/AAAAAAAAAEw/bRW_HKoglv8/s72-c/brick%20building%20sign.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1793810735609473964</id><published>2008-04-19T16:02:00.000-07:00</published><updated>2008-04-23T15:16:11.839-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='marginal utility'/><title type='text'>Python Hack - Unicode Sniffer</title><content type='html'>&lt;p&gt;Unfortunately, I sort of built the build system we use at work.&lt;/p&gt; &lt;p&gt;I say unfortunately because, since I'm the one that built it and I'm cheap, it was rolled with a minimum of brains and a maximum of free software.&lt;/p&gt; &lt;p&gt;On the database side of things, I use a handy little program called GSAR (global search and replace) that does what it sounds like it does - searches and replaces strings in files.&amp;nbsp; Unfortunately, it isn't exactly Unicode-aware, which means that files not saved as ASCII can slip through the cracks, causing subtle problems (depending on how subtle of a problem you see a missing piece of functionality being).&lt;/p&gt; &lt;p&gt;This normally wouldn't be a problem, but SQL Server Management Studio seems to flip a coin on installation to decide whether it's going to &lt;a href="http://www.sqljunkies.com/WebLog/outerjoin/archive/2006/10/03/23776.aspx"&gt;save files as ASCII or UCS-2/UTF-8/UTF-16 encoded by default&lt;/a&gt;.&amp;nbsp; Most computers in the office save files as ASCII, but there's a few that like to emit Unicode (especially when scripting out tables and stuff).&lt;/p&gt; &lt;p&gt;Like a hawk, or a ninja, or a ninja hawk, I quickly figure out who the offenders are and keep an eye on their check-ins.&amp;nbsp; I've got an RSS feed for the repository and, to be honest, they don't check in a whole lot of code so it's not a monstrous burden.&amp;nbsp; I keep an eye on check-ins anyway because, well.&amp;nbsp; I'm anal like that.&lt;/p&gt; &lt;p&gt;But why bother grepping the files manually when I've got a computer to do the grunt work for me?&amp;nbsp; I've been putting off knocking together a C# program to do it for me (why should I do it?&amp;nbsp; I'm not the one who sucks!), Ruby isn't so Unicode-savvy... but wait!&amp;nbsp; I'm a world-famous Python hacker now and Python knows Unicode!&lt;/p&gt; &lt;p&gt;So I put together a script that will recurse down the directory tree you put it in and, if it finds a file that isn't saved as Unicode, print its name out.&amp;nbsp; As a word of warning, it's not the greatest thing I've ever done and it catches binary files in its trawl line as well.&amp;nbsp; For my purposes, that's just fine - there's just text files living in the /Database portion of the central repository.&amp;nbsp; Now I can have it shut the build down when it finds the file straight-away.&amp;nbsp; Everyone goes home happy!&amp;nbsp; Except for the developers who got the bum install of SSMS and have to do some Save As... gymnastics every time they touch a file.&lt;/p&gt; &lt;p&gt;You can &lt;a href="http://dave.c.solomon.googlepages.com/UnicodeSniffer.py"&gt;grab the little script here&lt;/a&gt;.&amp;nbsp; Feel the magic!&amp;nbsp; Feel the power!&amp;nbsp; Marginal utility!&lt;/p&gt; &lt;p&gt;Oh, and I &lt;a href="http://48klocs.blogspot.com/2007/10/marginal-utility-isdebug-for-net-20.html"&gt;updated the links to my world-famous marginal utility IsDebug for .Net 2.0&lt;/a&gt;, too.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;4/23/2008 update - I've gone ahead and slapped the &lt;a href="http://sam.zoy.org/wtfpl/"&gt;WTFPL&lt;/a&gt; on it.  So do WTF you want with it now.  Or don't.  You won't hurt my feelings either way, honest.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1793810735609473964?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1793810735609473964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1793810735609473964' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1793810735609473964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1793810735609473964'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/04/python-hack-unicode-sniffer.html' title='Python Hack - Unicode Sniffer'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-3535369441773844069</id><published>2008-04-13T22:00:00.000-07:00</published><updated>2008-04-13T19:01:56.194-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='money money money money money'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>I don't care about money (except when I do)</title><content type='html'>&lt;p&gt;I walk and bike the same general paths on a regular basis, but every now and then I'll notice a really odd building or landmark and wonder how I went by it every day for months or years without noticing it, at which point I'll be struck by my ability to take something so obvious for granted.&lt;/p&gt; &lt;p&gt;I have the same reaction to reading - I'll read things and they'll resonate in a bizarre "how did you know I was thinking that" way.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;One thing that programmers &lt;em&gt;don’t&lt;/em&gt; care about&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;They don’t care about money, actually, unless you’re screwing up on the other things.&lt;/p&gt; &lt;p&gt; - Joel's &lt;a href="http://www.joelonsoftware.com/articles/FieldGuidetoDevelopers.html"&gt;Field Guide to Developers&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I hadn't ever really thought about it, but when I read that a few years back, it really did strike a chord.  When I got started developing professionally, I had to bike to work because I couldn't afford a car.  That was OK.  A few years later, people close to me told me that I needed to look for a new job because I was woefully underpaid (I was), but I still felt like I was learning so I never dusted off my resume.&lt;/p&gt; &lt;p&gt;Today I find myself in another awkward situation - I get paid more or less well but am completely unfulfilled by my job, but looking at the job market out there, I have to pick my jaw up off the ground.  I see companies just outside of major metropolitan areas offering $45K-$65K for senior developers with 5+ years of experience.  Normally I'd roll my eyes at another obvious H1B workaround, but these were genuine-sounding postings on developer-friendly spots (37 Signals/Joel on Software/The Daily WTF) and didn't have the laundry list of insane system experience for the lame salary they were offering.  I take one look at those job postings and immediately swat that tab closed.&lt;/p&gt; &lt;p&gt;But hold on a second - I thought I told myself that I don't care about money?&lt;/p&gt; &lt;p&gt;Well, here's the thing - I don't care about money, but I do care about respect.  I don't wake up sobbing each morning because the hundred thousand or so stock options I've been promised over the course of my career have been worth a total of 200 bucks (that's counting the plenty of options that are worth zero dollars because the companies went bust).  I didn't even cash them in because &lt;em&gt;&lt;strong&gt;what the fuck&lt;/strong&gt; two hundred dollars&lt;/em&gt;.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The value you put on stock is a measure of your belief in the company.&lt;/p&gt; &lt;p&gt; - Rands in Repose*, &lt;a href="http://www.randsinrepose.com/archives/2008/04/11/the_business.html"&gt;The Business&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Signing on to a start-up, you have no idea whether it'll go Google or go Pets.com (and it could go way worse than Pets.com), but if you don't believe that the options will be worth anything, it's already a sign that you should keep looking.&lt;/p&gt; &lt;p&gt;In the same way, I see salary as a measure of how much the company values its developers.  Are they looking to hire an intelligent person?  Will they be paying them enough money that it'd be borderline suicidally stupid for them to ignore their input into the product and process?  Or &lt;a href="http://weblog.raganwald.com/2008/01/no-disrespect.html"&gt;are they just looking for a clerk who happens to speak a little C#&lt;/a&gt;?  $45K-$65K fairly screams "dead-end clerk" to me, but it's no guarantee - you can make plenty more than that and still feel like a dead-end clerk.&lt;/p&gt; &lt;p&gt;I hate to sound like Joe Bitter or whatever, but when Jeff Atwood pondered &lt;a href="http://www.codinghorror.com/blog/archives/001097.html"&gt;why developers don't always use the best products that money can buy&lt;/a&gt;, instead opting for so-so free software, I knew the answer as soon as I saw the headline.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;It's so nice to just download the thing that gets the job done without having to fill out forms, get permission, wait for a PO, or anything.&lt;/p&gt; &lt;p&gt; - malcontent**, &lt;a href="http://reddit.com/r/programming/info/6f9sq/comments/c03ogg4"&gt;programming.reddit.com&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So, so very right.  When it comes to doing what I do for myself, I'm A-OK with figuring out what's the best for the job and paying money for it if I need it.  When it comes to work, I try to do the same, but how hard will I fight to get the resources bought for me that will make me more productive?&lt;/p&gt; &lt;p&gt;I've heard developers on forums talking about how they've bought their own licenses and that's just insane to me - why would I spend money to save my employers money?  I tried to get them to put out cash to support developers doing good work and instead, they end up putting out cash in the form of my time to support developers (me!) cobbling together mediocre (just kidding; my stuff's all brilliant!) workarounds.&lt;/p&gt; &lt;p&gt;Money it is an excellent signifier for figuring out just how important things are to people.  When gauging desire for features, it's the first thing I grab for - how many people will buy in because of this feature?  If it's a custom build, how much are they willing to pay for this feature?  Will they really walk if we don't deliver?&lt;/p&gt; &lt;p&gt;This is why open-source people get riled up when you ask how to do something trivial and will ask you where your patch is when you complain about "needed" features - you're implying that your time is more valuable than theirs.  They've already given you something free, and now you're rifling through their wallet looking for a $20 on top of it.&lt;/p&gt; &lt;p&gt;For someone who claims to not care about money, I find myself thinking about it more than I should, when I should be spending my time thinking about &lt;a href="http://48klocs.blogspot.com/2008/04/carrot-in-toaster.html"&gt;carrots in the toaster&lt;/a&gt; or something.&lt;/p&gt; &lt;p&gt;* Man, Rands really has come a long way from his days in &lt;a href="http://www.jerkcity.com/"&gt;Jerkcity&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;** How apropos a nickname is that?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-3535369441773844069?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/3535369441773844069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=3535369441773844069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3535369441773844069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3535369441773844069'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/04/i-don-care-about-money-except-when-i-do.html' title='I don&amp;#39;t care about money (except when I do)'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6083924559046403216</id><published>2008-04-13T18:50:00.000-07:00</published><updated>2008-04-13T18:54:58.610-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Carrot in the toaster</title><content type='html'>&lt;p&gt;I realize that it lacks the effortless panache of &lt;a href="http://www.youtube.com/watch?v=aqzNFnEjr_c"&gt;the banana in the tailpipe&lt;/a&gt;, but I'd like to introduce the world to a new, insane meme, the meaning of which will take generations to decipher - the carrot in the toaster.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5188911932778297602"&gt;&lt;img src="http://lh5.ggpht.com/dave.c.solomon/SAK36SwJOQI/AAAAAAAAAEo/C_M7ZHUt6bw/s400/banana%20in%20the%20toaster.JPG" /&gt;&lt;br/&gt; (blow it up!)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Come summertime, I like to grill carrots.  I'm OK with cooked carrots, honest.  But an unpeeled carrot thrown right in a grimy toaster oven?  There's something so very wrong with that.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is truly a disturbing world that we live in.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6083924559046403216?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6083924559046403216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6083924559046403216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6083924559046403216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6083924559046403216'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/04/carrot-in-toaster.html' title='Carrot in the toaster'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/dave.c.solomon/SAK36SwJOQI/AAAAAAAAAEo/C_M7ZHUt6bw/s72-c/banana%20in%20the%20toaster.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-2891056881688674578</id><published>2008-04-01T23:29:00.000-07:00</published><updated>2008-04-02T05:29:30.756-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>What does your app's codebase look like?</title><content type='html'>&lt;p&gt;I took this snapshot in the parking lot at my building.  I can't say that our application's architecture intentionally derived its inspiration from it, but there is an eerie similarity.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5181864747176771698"&gt;&lt;img src="http://lh5.google.com/dave.c.solomon/R-muiGmXQHI/AAAAAAAAADs/QM1QV6PkJ8U/s400/epic%20wall%20fail.jpg" /&gt;&lt;br /&gt;(click to blow up the tragedy)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?HaHaOnlySerious"&gt;Ha ha, only serious&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-2891056881688674578?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/2891056881688674578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=2891056881688674578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2891056881688674578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2891056881688674578'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/04/what-does-your-apps-codebase-look-like.html' title='What does your app&apos;s codebase look like?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5259192644538634611</id><published>2008-03-30T20:25:00.000-07:00</published><updated>2008-03-30T17:35:09.745-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>My (current) favorite picture in the world</title><content type='html'>&lt;p&gt;I was walking through downtown Manchester a couple of weeks ago, and this sign called out to me with its beautiful, terrible siren cry.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5181860782921957442"&gt;&lt;img src="http://lh6.google.com/dave.c.solomon/R-mq7WmXQEI/AAAAAAAAADM/PnKImXK1TpE/s400/fantastic%20street%20sign.jpg" /&gt;&lt;br /&gt;(click to blow it up)&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you're going to ask me what's so beautiful about it, you may as well ask me where it all went wrong and where you lost your soul from childhood up to here.  It's really the final admonition ("NO ESCORTS") that puts it over the top for me - it displays a remarkable economy of language that I obviously have no facility for.  At the very least, it tells the passer-by "we've been asked that goddamned question so many times we have to put it out in front so people don't ask again (and they probably will anyway)."&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I love this picture in an inappropriate way.  Or appropriate, I don't know.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5259192644538634611?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5259192644538634611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5259192644538634611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5259192644538634611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5259192644538634611'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/my-current-favorite-picture-in-world.html' title='My (current) favorite picture in the world'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7166677542611385836</id><published>2008-03-28T18:26:00.000-07:00</published><updated>2008-03-28T15:28:16.006-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='enterprise software'/><title type='text'>Taking your lumps like an enterprise</title><content type='html'>&lt;p&gt;Obie Fernandez &lt;a href="http://blog.obiefernandez.com/content/2008/03/sap-sued-for-ty.html"&gt;posted recently about SAP, enterprise software peddlers par excellance, getting their asses sued by Waste Management, a behemoth of a company, for a clusterfuck of a deployment&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This reminds me why I want to keep working for small companies - I want to know when other people are making absurd promises that they'll then expect me to uphold as soon as possible and if at all possible, I want to be able to correct them or speak directly to the client and say "Sorry, they fucked up when they said that.  Not gonna happen in that amount of time, but let's see how many items on that checklist we can realistically get done in the time and cost constraints you've set forth for us."  Scrum has embarrassingly juvenile terms, but I think they really nailed it with &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29#.22Pig.22_Roles"&gt;the pigs and chickens&lt;/a&gt; metaphor.&lt;/p&gt; &lt;p&gt;It also reminds me of a talk I had with my COO a few years back, back in the heady days when I thought software could solve all ills and had no interest in moving any further up the food chain than architect.  We were talking about some other clusterfuck that was in the news - a huge enterprise software vendor, a huge client, tens of millions of dollars and... nothing to show for it.&lt;/p&gt; &lt;p&gt;The developer in me was all righteous indignation - "How can they get away with that?  Isn't that kind of thing embezzlement or something?  If that were me, I would &lt;strong&gt;sue the bastards&lt;/strong&gt;."&lt;/p&gt; &lt;p&gt;His response (and I'm paraphrasing) was a thunderously mighty zenslap.&lt;/p&gt; &lt;p&gt;"There's no point in suing them."&lt;/p&gt; &lt;p&gt;"How can there be no point?  It'll serve notice to the next vendor in line that they're not to be trifled with."&lt;/p&gt; &lt;p&gt;"No, there's really no point.  Even if they win, they'll never recoup their costs.  They'll scare away other vendors and they still won't have what need.  It's over."&lt;/p&gt; &lt;p&gt;I couldn't argue with that.  I can't.&lt;/p&gt; &lt;p&gt;The contracts are dozens of miles long, filled with all manner of Cover Your Ass wording and dense, vague terminology that likely provide a Get Out of Jail free card to both sides.  It'll be tied up in the courts for years, but it doesn't change the essential problem - you've already slipped what you thought was your deadline and run over-budget.&lt;/p&gt; &lt;p&gt;Do you spend time, money and focus trying to chase what you already know is a dead-end or do you effectively shrug your shoulders and focus on what will make you money?  Were you completely up-front with all your needs?  Were they all clearly outlined (and signed in blood in the contract)?  Really?&lt;/p&gt; &lt;p&gt;And remember - if you do go with suing them, your chances of getting that software you swore you needed probably just evaporated.  That's money that's probably coming out of your implementation budget (which is, again, already exhausted).  If you could have done it in-house, you would have (right?) but you couldn't, so it means you need to find a new vendor.  Who is going to be &lt;em&gt;very&lt;/em&gt; wary of signing on with you because of the lawsuit, which means even more time and cost to get to the point where you can convince them to start building for you (which is going to take even more time and cost more because they know about your lawsuit and need to double-cover their asses).  Knowing that it'll be a pyrrhic victory at best, do you still sue?&lt;/p&gt; &lt;p&gt;So I'm surprised that Waste Management is nutting up and suing the holy bejeesus out of SAP.  I am, make no mistake about it, cheering for SAP to lose in the most majestic manner possible.  I hope other large companies sue other large, shitty, enterprise software vendors.&lt;/p&gt; &lt;p&gt;And I am hoping that when they're eradicated, I'll figure out a way to become the next SAP.  Money isn't the be-all and end-all, but I'm not too much of an asshole to say no to obscene amounts of money for nothing more than putting on a suit and having a nice little dog-and-pony show.&lt;/p&gt; &lt;p&gt;The difference between a shoplifter and a very successful enterprise software firm is that you're scared as fuck to prosecute the enterprise vendor when they rob you blind.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7166677542611385836?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7166677542611385836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7166677542611385836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7166677542611385836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7166677542611385836'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/taking-your-lumps-like-enterprise.html' title='Taking your lumps like an enterprise'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8893866097714567144</id><published>2008-03-25T22:00:00.000-07:00</published><updated>2008-03-25T19:11:57.976-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='picture time'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>So, about that Microsoft-Yahoo Merger</title><content type='html'>&lt;p&gt;So it was a slow day and I was reading about the Microsoft-Yahoo merger.  How developers at Yahoo are &lt;span style="font-weight: bold;"&gt;fleeing in droves&lt;/span&gt; because &lt;span style="font-style: italic;"&gt;Microsoft doesn't get the 'net and will ruin Yahoo&lt;/span&gt;.&lt;/p&gt; &lt;p&gt;And this isn't so say that they're wrong, but how about fleeing Yahoo for a better reason?  Like, say, because of this embarrassment puddle parked out on the street in front of my shonky whip?  I mean, come on Yahoo.  I've never seen a Googlemobile, but I suspect that they're not quite as... butch as this one is.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://picasaweb.google.com/dave.c.solomon/WindowsLiveWriter/photo?authkey=i8_uO9IvJwg#5181864751471739010"&gt;&lt;img src="http://lh6.google.com/dave.c.solomon/R-muiWmXQII/AAAAAAAAAD0/g7ZedplN958/s400/butch%20yahoo%20truck.jpg" border="0" /&gt;&lt;br /&gt;(click to engorge this shameful display)&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I've got no eye for color or detail, but... fuscia with the cheesy flame job?  Really?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Then again, it did bring a smile to my face.  For all the wrong reasons, but I was smiling.  Way to go, Yahoo.  Good luck keeping the corrupting influence of Microsoft far away from your pristine shores.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8893866097714567144?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8893866097714567144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8893866097714567144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8893866097714567144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8893866097714567144'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/so-about-that-microsoft-yahoo-merger.html' title='So, about that Microsoft-Yahoo Merger'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4292766099735194876</id><published>2008-03-23T18:04:00.000-07:00</published><updated>2008-04-19T13:03:49.095-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylot'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='watir'/><title type='text'>It's official - I'm a Python hacker!</title><content type='html'>&lt;p&gt;Lately, it hasn't been building the application that's captured my imagination so much as figuring out a way to validate the correctness of the application.  When you're dealing with a sprawling behemoth of an application of varying levels of quality (this isn't a dig at co-workers - I've got more than my share of turds baked in there) that's so absurdly data-driven that... well.  I've come to grips with the fact that chunk by chunk, we've built a borderline unmanageable enterprise application.&lt;/p&gt; &lt;p&gt;There's blocks of the application that I'm flat-out scared to touch because of their fragility.  There's a reason that &lt;a href="http://www.hasbro.com/games/family-games/jenga/"&gt;Jenga&lt;/a&gt; never took off as an application platform.&lt;/p&gt; &lt;p&gt;There's so many tables (I'll ballpark it at 300, but it could be more than that) that I have to walk through stored procedures and table definitions to figure out why many of them exist.  Thankfully, at least they're well-normalized even if, again, some are really, really arcane.&lt;/p&gt; &lt;p&gt;More interesting to me than anything else lately is testing the application.  When it comes to a giant database-driven web application, there are no easy answers to "how do you prove it is working correctly?".  Well, at least none that The Google is willing to impart on me.&lt;/p&gt; &lt;p&gt;As &lt;a href="http://48klocs.blogspot.com/2008/03/working-hard-to-get-you-fired.html"&gt;I've mentioned before&lt;/a&gt; and will be talking about again soon (I'm busy hacking, d00dz!), I heart the hell out of &lt;a href="http://wtr.rubyforge.org/index.html"&gt;Watir&lt;/a&gt;.  You run &lt;a href="http://svn.openqa.org/svn/watir-recorder/trunk/Ruby/src/WatirMaker.rb"&gt;WatirMaker&lt;/a&gt;, you walk through your application, you're 80% or more of your way to a test case.  But... it runs slow.  It takes over 3 hours to run 130-ish test cases of varying complexity on the old desktop I snuck the regression automation environment on to.  I love it, but I worry about its scalability.&lt;/p&gt; &lt;p&gt;Over on programming.reddit, I saw a new tool announced that tickled me in all the right spots - &lt;a href="http://www.pylot.org/"&gt;Pylot&lt;/a&gt;.  It was designed as a web load-testing tool (I've seen the QA folks at work use Quick Test Pro, but it's a fragile piece of shit if I've ever seen (and built) one) and has lightweight validation features built into it.  On that end, it's not as fully-featured as Watir (I've updated WatirMaker to do 31337 things like generate automagic tests when you click on text in table cells/spans/the body) but... speed!  Free replacement for Quick Test Pro (maybe)!&lt;/p&gt; &lt;p&gt;I saw it and immediately got to wondering about writing tests for it - is there anything that will get me 80% there?  Not yet.  Could I take WatirMaker and update it so that it emits Pylot-friendly XML?  Sure, but doesn't that feel just a lot unholy?&lt;/p&gt; &lt;p&gt;So I downloaded Python and got to work doing the crappiest, stripped-down-est translation of a useful Ruby meta-script to Python that you've ever seen.  A few hours of grunting and banging my head later, I've got something to show for it, thanks in part to the duders over in #python on EFNet.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;daves&gt; Does anyone have any experience working with buffer objects? I'm getting one handed back to me and I'm completely lost as to how to coax it back to a string.&lt;/p&gt; &lt;p&gt;&lt;sven&gt; um, str(yourbuffer)&lt;/p&gt; &lt;p&gt;&lt;gjvc&gt; that's what makes python so difficult to pick up -- its simplicity&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If I were them, I'd clown on me too.  In my defense, The Google wasn't all that helpful when it came to working with buffers in Python and I'm a complete new jack and calling yourbuffer.tostring() wasn't getting me anywhere useful and enough ball-aching.&lt;/p&gt; &lt;p&gt;&lt;a href="http://dave.c.solomon.googlepages.com/PylotMaker.py"&gt;So here's my first stab at PylotMaker.py&lt;/a&gt;.  It requires the &lt;a href="http://sourceforge.net/projects/pywin32/"&gt;Win32 extensions for Python&lt;/a&gt; to run and you run it the same way as WatirMaker - pop open a command prompt and "PylotMaker.py &gt; test.xml", browse around the Internet Explorer window that opens up, close IE when you're done and test.xml is set up for you.  Minus tests.&lt;/p&gt;Did I really spend 5 hours knocking out 44 lines of Python instead of playing &lt;a href="http://orange.half-life2.com/tf2.html"&gt;Team Fortress 2&lt;/a&gt;?  There's something way wrong with me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4292766099735194876?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4292766099735194876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4292766099735194876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4292766099735194876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4292766099735194876'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/its-official-im-python-hacker.html' title='It&apos;s official - I&apos;m a Python hacker!'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5838335207015374794</id><published>2008-03-19T21:53:00.000-07:00</published><updated>2008-03-19T18:55:06.942-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>A Few Binary Propositions I'm Comfortable Making</title><content type='html'>&lt;p&gt;By the time I got to high school, I was ready to &lt;em&gt;get serious&lt;/em&gt; about programming.  OK, not get serious, but at least take some classes in it because &lt;strong&gt;that's how you meet ladies&lt;/strong&gt; (note: that's not how you meet ladies).&lt;/p&gt; &lt;p&gt;I learned some lessons that I regarded as stupid then and quaint now (pseudocode your program completely before you sit down at a keyboard (read: hi UML or we pay for cycles on the VAX cluster)), but I also learned some rules which have honest to god stood the test of time.&lt;/p&gt; &lt;p&gt;When it comes to programming, I'm pretty uncomfortable making binary propositions - there's a time and a place for a lot of things.  That time isn't the future because in hindsight, you can count on recognizing just how wrong you were to think that you could get away with that.&lt;/p&gt; &lt;p&gt;But fret not!  Here are a (very) few rules that you will never kick yourself for following.  These are &lt;strong&gt;laws&lt;/strong&gt;.  These are &lt;strong&gt;immutable&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;Use clear, concise, self-descriptive variable names&lt;/span&gt;&lt;/p&gt; &lt;p&gt;Our task was to write a function to calculate the area of a rectangle.  After laboriously pseudocoding it out, I sat down in Turbo Pascal and banged out some gorgeously hand-crafted code, using x1 and x2 as parameters for the length and width because they were easy to type.  It worked.  &lt;em&gt;Flawlessly&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;My teacher took a look at the print-out of my code and asked "Why not call them length and width instead?"  I started to argue because that's how I roll, but then it hit me like a &lt;a href="http://c2.com/cgi/wiki?ZenSlap"&gt;Zen slap&lt;/a&gt; - &lt;strong&gt;code is words, structured a bit differently and with a bunch of funny-looking symbols interrupting it, but you should try to make it as readable as possible&lt;/strong&gt;.  This starts with meaningful variable names and grows from there.&lt;/p&gt; &lt;p&gt;Thankfully, this is one rule that I don't break.  Ever.&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;&lt;/span&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;You should be able to describe what any function does in one sentence (and the word "and" should not be part of that sentence)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;I try to decompose my functions, but I'm not nearly merciless enough in my pursuit of it.  I don't set out to get there, but big gnarly if blocks in my business logic can spiral methods out of control, leaving me at the point where I'm afraid to extract out blocks because things might break.&lt;/p&gt; &lt;p&gt;This is probably reason enough to extract out blocks, but I'm bullshitting myself into not doing it for any number of reasons - I tell myself things like "the code is complex because it's modeling a complex process" but I know just how much of a cop-out that is.  It's lame and embarrassing and if only that code weren't working and I wasn't so afraid of it, I'd do something about it.&lt;/p&gt; &lt;p&gt;Honest.  Probably.&lt;/p&gt; &lt;p&gt;Thanks to playing around in Haskell, I'm rediscovering just how powerful decomposition can be.  You can, like, build big things out of little things and stuff.  It's easier than the God Functions because you're just building ever-bigger functions out of ever-smaller, easy-to-test functions.&lt;/p&gt; &lt;p&gt;Next time I'll get it right.  I hope.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;A cat should be able to walk across the keyboard without interrupting your program&lt;/span&gt;&lt;/p&gt; &lt;p&gt;Does this sound like "validate client input"?  Because it is.  If you want to be fancy about it, you could say "don't trust client data any more than you absolutely have to."  Either way, this is rock-solid advice.&lt;/p&gt; &lt;p&gt;You should not be building software where you're afraid to enter a number for a name, a letter in a date or (god help you because I've used garbage like this) click in a form while it's processing because something disastrous will happen.&lt;/p&gt; &lt;p&gt;I also manage to not break this (most of the time).  That said, when I do things like, say, set maximum lengths on input boxes on my pages and don't test the form data on the server side, I have a pang of guilt that I'm not really solving this properly (and I ignore it and move on).&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;When the dam breaks, work on the first problem first&lt;/span&gt;&lt;/p&gt; &lt;p&gt;The blogosphere will tell you that this is &lt;a href="http://smuglispweeny.blogspot.com/2008/03/tiltons-law-solve-first-problem.html"&gt;Tilton's law&lt;/a&gt;.  When our programs would invariably break, I'd look at the jumble of garbage on the screen and start inventing ever more elaborate explanations for what just happened.  Maybe I overwrote the video buffer with a whoosiwhatsit and flargened the backplane with a sympatasultic bitmask!&lt;/p&gt; &lt;p&gt;My teacher sat down and asked me what went wrong.  I started to spout some nonsense about this and that.  He listened to me for a minute, then stopped me and said "Why don't we start from the beginning and see where it leads us?"  Surprise surprise, I'd made some bonehead mistake or other (but 17 years later, I couldn't tell you what).&lt;/p&gt; &lt;p&gt;This came back to haunt me just today.  A &lt;strong&gt;hot issue that must be fixed now&lt;/strong&gt; got dropped in my lap yesterday in an application that's kind of sort of orthogonal to the one that I develop and support.  So I start looking into it, but I can't get it to run out of the box.  I fight with it more and more and more and a day and a half gets burned making just about no progress as I'm trying to chase the downstream effects, waiting for them to lead me back to the cause.&lt;/p&gt; &lt;p&gt;We get on a conference call to talk about the status and I hear people say what they were trying to do (it had been e-mailed to me before) and it clicks - check the data setup.&lt;/p&gt; &lt;p&gt;I'd taken for granted that someone else had done this already, but lo and behold - it's wrong.  12 hours of wasted time could have been saved by 5 minutes of fact-checking.&lt;/p&gt; &lt;p&gt;It's easy to get caught up in Rube Goldberg contraptions to explain what could have gone wrong and on some perverse level kind of fun, but on another, it's more fun to start simple and fix the root problem rather than chasing a symptom.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;I'm batting .500 or so.  It's enough to get me to the big leagues, right?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5838335207015374794?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5838335207015374794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5838335207015374794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5838335207015374794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5838335207015374794'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/few-binary-propositions-i-comfortable.html' title='A Few Binary Propositions I&amp;#39;m Comfortable Making'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-3208798913759990465</id><published>2008-03-02T20:28:00.000-08:00</published><updated>2008-03-02T20:08:57.007-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qa'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='watir'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Working Hard to Get You Fired</title><content type='html'>&lt;p&gt;When we first started porting from ASP 3.0 to C#, I'd never heard of test-driven design (why hast thou forsaken me (in 2000), blogosphere?!??!).&lt;/p&gt; &lt;p&gt;When we had a second round of developer hires, the two guys were gung-ho to get us on the Path Of Continuous Integration and get us all test driven and stuff.  Were it not for the fact that we already had 200-odd KLoCs of legacy code of varying quality that would need to be refactored to be testable (in retrospect, I'm aware of just how big of a cop-out that is) and deadlines looming, we might have gotten on board the TDD train.  But had the blinders on, so that never happened.&lt;/p&gt; &lt;p&gt;I've done some refactoring to bake in poor man's testability (objects that audit themselves and throw exceptions for as many offenses as possible) but the fact remains that building new functionality and fixing old issues often feels like sticking thumbs in the dam - I can feel when something's going to break, I just can't tell what or where.&lt;/p&gt; &lt;p&gt;About a year ago, the QA department hired someone to do automation for them.  I was pretty pumped about it the application that we've built is that it's so big (400 KLoCs of C#, some ASP.Net controls, another 75-100KLoCs of T-SQL, bits and pieces of BizTalk) and so data-driven, at this point it would take something just short of an act of god to get it to a point where it's testable.  I have little to no desire to be part of that and have never pushed for that sort of intra-object testing.  I remain unsold on the promise of TDD, but I'm not so arrogant as to completely discount it; it's more that, like security, it's not something that can be bolted on.  Maybe.&lt;/p&gt; &lt;p&gt;Simulated end-user QA automation - that's the testing that I can get on board with.  I've been using the super-hella-sweet &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt; for a while now and have handed it out to developers, product development, QA, even customer service reps when I want to replicate problems; it's been a godsend.  I've built smoke tests that I can run on each deployment build that have saved my bacon more than once.  I don't know how much you can tell about how the application's working or not working from inside of an object, but it's pretty easy to tell when things aren't working with it when your scripts break while being run.&lt;/p&gt; &lt;p&gt;The QA automation guy?  Nice enough chap.  He's personable, seems to know what he's doing and all, but... a year in and I've got no test suite to run.  Enterprise-grade tools mean awkward enterprise licenses (we actually run a fucking license server somewhere or other- what the shit is that?) and all the user-friendly quality you'd expect from anything enterprisey.  Plus I suspect that the goals were too lofty, that they were intent on building something beautiful and perfect and settling for nothing less.  Which is great and all, but &lt;em&gt;daddy wants his application tested already&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;We've hit one of our cyclical lull periods at work.  This isn't to say that there aren't issues cropping up all the time, patches being sloppily built and hurriedly and incompletely tested (business as usual!), just that the volume of issues is decreasing and management's hemming and hawing about what new features to build out.  I've been sitting on my hands, getting micromanaged on what issues need fixing and what can be left to slide, so I took a look in my Watir folder - hey look, 100-odd scripts testing and regressing issues that we've logged for the past year or so.  Most of them broken at this point because of genuine application changes, but whatever.&lt;/p&gt; &lt;p&gt;I set out to fulfilling the promise I saw in testing when I first brought it up - that not only were we saving time with each test, but that we were organically building up a test suite, testing the things we needed to.  Getting all of my test scripts working was step one.  Step two, the uglier step, was taking the user out of it.  Before, I was relying on the end user (the QA person it was aimed at) to push a button in an internal GUI here, look at a piece of data there.  But with a few Ruby system() calls and poking at the content of spans and tables (time-consuming as that is), that's fallen by the wayside.&lt;/p&gt; &lt;p&gt;The next hurdle was the database side of things - there's some pieces of data that don't make themselves evident in the application to the end user, so how the hell am I supposed to test for those?  Oh - &lt;a href="http://msdn2.microsoft.com/en-us/library/ms188714.aspx"&gt;you can pass variables (like the auto-generated user's ID) in to SQLCMD&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So a week and change of me ignoring this and that piddly little issue later, and I've got 3 dozen or so scripts built out and &lt;strong&gt;checking things&lt;/strong&gt;.  Another couple of weeks or so and I'm going to have an honest-to-god test suite and, if anyone's paying attention, a QA automation pro's going to have some explaining to do when I've come correct with a reasonably not-too-shitty regression suite in what amounts to my free time and he's over a year in and still hasn't produced smoke tests.  And if no one's paying attention and nobody gets canned for it, I'm not losing any sleep over it because I'll have scratched one hell of a big itch.&lt;/p&gt; &lt;p&gt;If only my solution was enterprise-grade, we'd be able to use it too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-3208798913759990465?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/3208798913759990465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=3208798913759990465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3208798913759990465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3208798913759990465'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/03/working-hard-to-get-you-fired.html' title='Working Hard to Get You Fired'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7816023238113911426</id><published>2008-02-02T19:23:00.000-08:00</published><updated>2008-02-02T17:30:04.014-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Breaking the Hype Cycle</title><content type='html'>&lt;p&gt;Like a good .Net drone (haw haw), I rambled on down to Waltham, Mass. this past Thursday to get introduced to the brave new world of .Net 3.5 and Visual Studio 2008.&lt;/p&gt; &lt;p&gt;I found myself going through various phases of confusion, boredom and then (eventually) excitement.  Confusion over &lt;a href="http://www.davidchappell.com/blog/"&gt;David Chappell&lt;/a&gt; (sadly, not the sometimes Rick James impressario) and his speech there.  Given that he's written books on stuffs, has a consulting firm and talked about opening for Bill Gates at some development conference, I take it that he knows his thing.  That's great and all, but... this was a developer's conference or so I thought?  The man can give a good speech, but I'm still clueless as to why he felt the need to sell developers on the .Net ecosystem as a viable platform.  Preaching to the converted and all that.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/tmancini/"&gt;Todd Mancini&lt;/a&gt; came out next to give a talk on Visual Studio Team System.  When I first started reading about it, it felt like it was just another enterprise Rorschach test but seeing concrete examples of what it does (how many use cases have been fulfilled, how many have been tested by QA, how many have unit tests, code churn, yadda yadda) I can see that behind the scenes it's a pretty slick little piece of work... more on that later.&lt;/p&gt; &lt;p&gt;I was remarkably confused by the talk that &lt;a href="http://blogs.msdn.com/allandcp/"&gt;Allan da Costa Pinto&lt;/a&gt; gave.  I'd signed up for a couple of sessions on .Net 3.5 and Visual Studio 2008 and for some reason got treated to an hour and a half on Windows Workflow Foundation and the Windows Communication Framework.  He gave an OK enough presentation, but goddamned if I could tell you what either of the technologies are.  Repeated over and over is that "you can paint your business processes" but what drawing a workflow diagram's achieving me is still beyond me.  I get the feeling that there must be a lot in there, but I also have no idea what's in there or why I'd want to use it.  Maybe it's targeted at a different user space or maybe it's a solution in search of a problem?  I do know that you can start a process and wait up to 30 days to take the next step in it!  Yes, it means fuck all to me too.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/cbowen/"&gt;Chris Bowen&lt;/a&gt;, the last speaker of the day, was finally the guy who got me excited to have gone down there.  Away with the 10,000 foot view of what's new with the .Net platform (too goddamned much to follow) and into the new language features (anonymous functions!  anonymous types!  lambda expressions!  extension methods!  all that good shit that perversely makes perfect sense since I've been embarrassing myself by trying to wrap my head around Haskell and functional programming) and a good, quick, runthrough of LINQ.&lt;/p&gt; &lt;p&gt;When I first heard about LINQ, it sounded kind of retarded to me.  Hey look, it's sort of SQL.  Except the select clause comes at the end and it's uglier?  No thanks!  How is this supposed to do anything for me?  Why would I want to write not-quite-SQL and then deal with object/relation impedance on top of that?  I can see it working for CRUD, but I've got joins that pull together 25 tables (god help me) and I really have no desire to try to get that to work in code.&lt;/p&gt; &lt;p&gt;But curiously, seeing it in action, it all made sense.  LINQ-to-SQL is something that actually had my mouth watering.  That same terrifying stored procedure I mentioned relies on an underlying user-defined function that broke the other day as well as views as well as... well, you get the picture.  I'm mixing and matching business logic with data retrieval logic and I'm not happy about it.  I was never really sold on having data retrieval logic in the business classes (I dallied OR mappers and was never really impressed by what they were doing for me) but I'm changing my mind now.&lt;/p&gt; &lt;p&gt;Autogenerated paramaterized SQL queries?  Internet says that &lt;a href="http://blog.codeville.net/2007/12/13/outsmarted-by-linq-to-sql/"&gt;LINQ-to-SQL can actually outsmart you&lt;/a&gt; when it comes to query optimization... not that this is saying much when it comes to my SQL-fu.  Chris gave a run-through of the features that went from what they were in clear terms to how they work in clear terms, and it all really clicked.  I was pumped to go home and start ripping out that library of 250-odd stored procedures and start rewriting them in LINQ-to-SQL!&lt;br /&gt;Except, oh yeah.  We already have 250-odd stored procedures and they generally run pretty well.  Writing them isn't hard, maintaining them isn't that bad.  Sure, we've got business logic turds floating in our database punchbowl, but I'm too lazy to fish them out when I've got so many freaking bugs in the application to fix.  The language features are really nice (extension methods still have my mouth watering) but by the time I was in the elevator down, I could already feel my excitement to Change The Way We Program dying as I got to thinking what Fred Brooks would say - this all is attacking accidental complexity, leaving the essential complexity of what we do untouched.&lt;/p&gt; &lt;p&gt;So it was the talk on Visual Studio Team System that left me the most sort of excited.  The idea that the application forces you to work in sane, cohesive process (unit tested code, tracking user stories and the work projects associated with making them happen, lines of code, bugs open with the stories) seems like it'd be forcing you into dealing with the essential complexity of software development.  Rather than pretend that you can crush that Gantt chart down and cut QA out of the cycle, you're forced to accept the fact that the constituent components of the project are missing in action and until that's done, the application isn't.&lt;/p&gt; &lt;p&gt;Nice stuff.  Now all I have to do is find a company that'd understand the need for it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7816023238113911426?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7816023238113911426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7816023238113911426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7816023238113911426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7816023238113911426'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/02/breaking-hype-cycle.html' title='Breaking the Hype Cycle'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7707810022260508424</id><published>2008-01-22T23:51:00.000-08:00</published><updated>2008-01-22T20:53:17.507-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>How I Got My Silver Programmer Certificate</title><content type='html'>&lt;p&gt;OK, I didn't.  It doesn't exist.  It won't exist.&lt;/p&gt; &lt;p&gt;There's more than one way to look at the ongoing kerfuffle over whether schools are falling down on the job or not.  You can play the hyper-cynical devil's advocate and point out that &lt;a href="http://weblog.raganwald.com/2008/01/no-disrespect.html"&gt;in a sense, undergraduate computer science degrees are right up there with vo-tech degrees&lt;/a&gt; (not that there's anything wrong with that).&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;a degree is only as meaningful as its scarcity&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Which brings us to another way to look at it - we can quit the ball-aching already because the knowledge that colleges are teaching Java instead of Lisp means pretty much fuck-all for us.  Seriously.  If I'm staffing for a company, I'm not pinning my hopes and dreams for future success on the fact that I've got a few recent computer science graduates working for me, even if they're from an ostensibly top-tier school.  I'm hiring the guys with track records for delivering software that can talk the business domain talk (and it's a really awesome bonus if they can talk radix tries too).&lt;/p&gt; &lt;p&gt;College degrees don't prove that you're ready to develop in the real world.  &lt;strong&gt;Holy shit.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Wait.  &lt;a href="http://48klocs.blogspot.com/2008/01/meaningful-certification-is-hard.html"&gt;This is news&lt;/a&gt;?&lt;/p&gt; &lt;p&gt;Certificates, whether they're diplomas, training certificates, passing the bar, getting your doctor stethoscope, being a certified engineer, whatever - I read them as signifying one thing only - "this person's certified to prevent me from doing anything immediately catastrophic."  The lawyer may be grossly incompetent at what they do, but they'll be able to advise you enough to not land you on death row for your parking tickets.  The doctor's not going to prescribe dioxin for that headache.  The engineer's not going to say "what the hell, it might work" to your grand plan to replace the steel girder wire on the bridge with Silly Putty.  That comp sci grad will probably be able to put something together that compiles.&lt;/p&gt; &lt;p&gt;You're looking for a piece of paper that certifies that the holder is an all-world programmer who's going to fix all your code problems?  &lt;a href="http://www.knowing.net/PermaLink,guid,1d5b10b4-c271-4478-bd2e-3726c7519546.aspx"&gt;Sorry, doesn't exist.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Still another takeaway from this - enough already with whatever feedback loop there may be.  Businesses think that they need more computer people, so they drive up demand for comp sci graduates, so colleges lower the bar for what it means to be a comp sci graduate so you can get churned out to go work at a conglomerate.  I'm a schlub who went this route (or this route found me, your call), so who am I to turn my nose up at it?&lt;/p&gt; &lt;p&gt;This seems to presuppose the notion that there's a supply-side fix to be made here - get businesses to understand just how meaningless the comp sci degrees are and academia will disentangle itself from business and we'll find ourselves in some sort of OK-well-maybe-it-never-existed nirvana where every computer science graduate can knock out a generational garbage collector blindfolded and works on their own system kernel just for kicks; that academia's gotten too caught up in what business needs rather than keeping their heads in the clouds and looking decades down the road.&lt;/p&gt; &lt;p&gt;I don't buy it.  I became a programmer because I've got a terrible craving for learning.  I think that's the thread that underscores all at least mediocre programmers - we're auto-didacts.  It's why I giggle to myself when I see the "how can I teach my son to program" question thrown out there.  If they really want to, they'll find a way.  If they have to be dragged there, I'm sure they'll find a 9-5 in the cube next to mine some day.&lt;/p&gt; &lt;p&gt;It's why I'm left scratching my head about people bemoaning the death of the comp sci degree.  Saying silly things like "you go to school to learn how to learn."  Bullshit.  You're born knowing how to learn.  Some people will learn no matter what, others are content with what they've learned and will figure out how to apply it in new, interesting and sometimes inappropriate ways and still others make me wonder just how fictional &lt;a href="http://us.imdb.com/title/tt0387808/"&gt;Idiocracy&lt;/a&gt; was (kidding! (maybe)).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7707810022260508424?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7707810022260508424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7707810022260508424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7707810022260508424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7707810022260508424'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/01/how-i-got-my-silver-programmer.html' title='How I Got My Silver Programmer Certificate'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1344407629198295483</id><published>2008-01-15T22:16:00.000-08:00</published><updated>2008-01-15T19:17:38.126-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ride &apos;em cowboy'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>Management Conundrums - The Cowboy</title><content type='html'>&lt;p&gt;I read &lt;a href="http://www.infoq.com/news/2008/01/crunch-mode"&gt;an article refuting the value of crunch time&lt;/a&gt; and got to wondering about it.&lt;br /&gt;I've been the cowboy before, working 100+ hour weeks. Dreaming in code, pulling 24 hour days, a real Team Player.  I don't want to ever go back there again.  I'd like to prevent people I work with from going there too.&lt;br /&gt;I found crunch time to be a vicious cycle.  Rather than sit back and think my way through the problem, I dove in head-first and bumped my head on the bottom.  Hard.  Repeatedly.&lt;br /&gt;I found myself working long hours, making mistakes along the way, and then working longer hours because I told myself "I'll just fix this later."  And then working longer days because I couldn't remember the fix that I had in my head earlier but it all seemed so clear to me and in retrospect, fuck embracing &lt;a href="http://www.c2.com/cgi/wiki?DeathMarchValues"&gt;death march values&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;To push my street cred through the roof, I'll just quote &lt;a href="http://en.wikipedia.org/wiki/Bun_B"&gt;Bun B&lt;/a&gt; who puts it better than I do.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Start with your head, homie, then use your hands / If you try it in reverse, you don't even stand a chance.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I don't know if it's confirmation bias on my part - I'm a pretty lazy guy (note to anyone daydreaming of hiring me: I'm &lt;span style="font-weight: bold;"&gt;totally&lt;/span&gt; joking about that). Am I just buying into what these people and their so-called "studies" are saying because I'm (*cough* not) lazy and want to believe anyone that's telling me that working a square 40 hours a week is really OK and even preferable?&lt;/p&gt; &lt;p&gt;The thing is, not everyone believes it - and this is not just managers that I'm talking about, either.  As &lt;a href="http://programming.reddit.com/info/656pn/comments"&gt;the comments on the article over on programming.reddit&lt;/a&gt; show (and as my anecdotes reinforce), some developers have an almost bloodthirsty need to believe in the power of crunch time.  There were a couple of chaps in there extolling the virtues of brutal hours of work, stating that without doing months of crunch mode, their projects wouldn't have finished.  I prodded, trying to lead them down a path to questioning whether the projects might have finished in the same amount of time without crunching for it, but it was rejected out-of-hand.&lt;/p&gt; &lt;p&gt;&lt;u&gt;The Mythical Man-Month&lt;/u&gt; gave us the should-be-more-famous truism that "you can’t get a baby in one month from 9 women" - some tasks really are going to take a set amount time no matter how many resources you throw at them.  The mother can start pushing on day one or wait until month nine to start pushing; the baby's not coming out any faster no matter how many months she's been pushing.  I think that believing that you can accelerate nature (I'm talking development projects now not babies; work with me, people) is equal parts foolhardy and arrogant, but I also think that a good developer needs a healthy dose of both of these qualities.&lt;/p&gt; &lt;p&gt;When it's a team gelling and putting in the overtime because they want and need to, you let it go.  That's a no-brainer.  Of course, you can't go on auto-pilot.  You need to figure out when they're sprinting to a dead end, when they've started sprinting too soon and have been sprinting so hard that it's counter-productive and maybe you should kick them the fuck out of the office at 5 PM on Friday so they can see their families and come back ready to do good work on Monday.  You need to reel them in at some point.  Like any design pattern, "crunch time" has its use.  Just take care to not treat it like a &lt;a href="http://haacked.com/archive/2005/05/31/3935.aspx"&gt;golden hammer&lt;/a&gt; and you'll be fine.&lt;/p&gt; &lt;p&gt;It's the lone cowboy that I'm concerned about, and I'm concerned about what to do with them.  When it's a team working to a goal, they're building together.  When it's the lone person banging away at all hours, they're using their back more than their brain and will miss simple, obvious solutions to their problems and get aggravated at everyone else who isn't putting in the same brutal hours they are.&lt;/p&gt; &lt;p&gt;Part of me wants to save them, but then again I'm not sure that anything &lt;strong&gt;can&lt;/strong&gt; be done with or for them.  Reason, logic and studies seem to bounce off of them (it did off of me) like bullets off of Superman's skin.&lt;/p&gt; &lt;p&gt;At my current job, we had a cowboy developer.  Good developer, smart guy, put in long-ass hours.  Went on vacation, came back in with a custom XML business rules engine (like &lt;a href="http://labs.jboss.com/drools/"&gt;Drools&lt;/a&gt;) that used .Net Reflection and all that good stuff to drive it.  It's pretty good code, just that in retrospect... we didn't really need it.  I never had the heart to tell him that outright and thousands of lines of code nobody wants to refactor out of the application remain today.&lt;/p&gt; &lt;p&gt;When he eventually left, another of our developers quietly became the new "hard worker" to pick up the imaginary slack left behind.  I don't know that I'd even have noticed this quiet change if I hadn't read &lt;a href="http://www.amazon.com/Lucifer-Principle-Scientific-Expedition-History/dp/0871136643/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1200333840&amp;amp;sr=8-1"&gt;The Lucifer Principle&lt;/a&gt; by Howard Bloom (this and &lt;a href="http://www.amazon.com/48-Laws-Power-Robert-Greene/dp/0140280197/ref=pd_bbs_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1200333878&amp;amp;sr=1-2"&gt;The 48 Laws of Power&lt;/a&gt; are Dave Solomon picks for bizarroland must-read management books).&lt;/p&gt; &lt;p&gt;In &lt;u&gt;The Lucifer Principle&lt;/u&gt;, Bloom relates &lt;a href="http://books.google.com/books?id=YctWRSbQessC&amp;amp;pg=PA92&amp;amp;lpg=PA92&amp;amp;dq=lucifer+principle+bully&amp;amp;source=web&amp;amp;ots=6nUjt9Me__&amp;amp;sig=WC95QlB8TOFZ6wP7uY7k3Hd2tyY#PPA92,M1"&gt;an anecdote about a researcher's study at a summer camp.&lt;/a&gt;  The researcher had identified four major archetypes for kids in group behavior - the "alpha male", the "bully", the "joker" and the "nerd" and conducted an experiment with them (nothing on the level of &lt;a href="http://en.wikipedia.org/wiki/Stanley_Milgram"&gt;Milgram&lt;/a&gt; or the &lt;a href="http://www.prisonexp.org/"&gt;Stanford Prison Experiment&lt;/a&gt;).&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The scientist assembled a cabin composed entirely of "leaders," boys who had been dominant, "alpha males" in their old groups.  Very quickly, the new cluster sorted itself out according to the familiar pattern.  One of the leaders took charge.  Another became the bully.  A third became the group joker.  And one of the formerly commanding lads even became the new group's nerd.&lt;/p&gt; &lt;p&gt;- The Lucifer Principle, Howard Bloom, pg. 92&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I know I'm doing a terrible job explaining this, but what it comes down to is that I've seen the shift in my co-worker and I don't think it's a conscious one.  He may think that he "needs" to work longer hours (I've certainly danced around it trying to get him to feather the brake pedal on it, so to speak) to get things to work, but could he explain why?&lt;/p&gt; &lt;p&gt;Of course, self-interest on my part demands that I don't push them too hard to not kill themselves.  I'm not the boss and if he's not doing the long hours, I'm sort of afraid that someone else is going to give me the stink eye because I'm not checking in code after midnight just before I leave on vacation to show that I'm a team player, never mind that the code's invariably broken in some hideous ways and people are going to have to quickly find and fix all the mistakes I've made because I was tired and rushing.&lt;/p&gt; &lt;p&gt;Moreover, like I said, I suspect that there's some subconscious understanding about the archetypes (for developers, read: "design pattern") of a team, and that the "overachiever" is one of them.  I know just how loaded the word &lt;a href="http://en.wikipedia.org/wiki/Jungian_archetypes"&gt;archetype&lt;/a&gt; is which is why I think it's probably an aft metaphor - if our work habits are indeed an unconscious manifestation of our identity, then there's no clean way to divorce one from the other - the cowboy's going to keep drawing for that six-shooter no matter what you do and resent you for telling him to keep it on safety before he blows his foot off.  They may not be able to do it any more than you could conquer someone's fear of snakes just by bringing to their attention the fact that they are, in fact, terrified of snakes (I suspect this is an easier one to break though).  Moreover, you get rid of one and another will rise to the occasion.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Unless you do what you can to make them and everyone else on the team aware of your distaste for their overwork and unless your boss (and &lt;a href="http://en.wikipedia.org/wiki/Turtles_all_the_way_down"&gt;bosses all the way up&lt;/a&gt;) are on board with holding people to a square forty, I doubt it will happen.&lt;/p&gt; &lt;p&gt;Sadly, getting everyone to throw fallacious common sense overboard and accept the fact that working smarter and working harder are just about always mutually exclusive and working smarter beats working harder just about every time isn't an easy task.  If it was easy and if these work archetypes didn't exist, then everyone wouldn't be &lt;span style="font-style: italic;"&gt;positive&lt;/span&gt; that today's Dilbert (for pretty much any value of Dilbert) &lt;span style="font-style: italic; font-weight: bold;"&gt;just had&lt;/span&gt; to have been sent in by one of their co-workers.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;But I'm no manager, so I keep on doing what I can to make things better, forty hours a week.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1344407629198295483?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1344407629198295483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1344407629198295483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1344407629198295483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1344407629198295483'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/01/management-conundrums-cowboy.html' title='Management Conundrums - The Cowboy'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8692910019742550254</id><published>2008-01-09T22:28:00.000-08:00</published><updated>2008-01-09T19:29:40.828-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interviews'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>Meaningful Certification is Hard</title><content type='html'>&lt;p&gt;When I read Raganwald's &lt;a href="http://weblog.raganwald.com/2007/07/certification-bring-it-on.html"&gt;post on certification&lt;/a&gt; a while back, I was impressed by what laid underneath the surface.  What he's looking to certify out of the gate is a first-pass cut to weed out the scrubs and find people with a shared set of values that is not up for discussion - no matter what you're doing or how you're doing it, if you can't prove that you're doing it correctly and safely, it hasn't been done.  I like the idea because it implicitly weeds out the people who can't program all that well in the first place; if getting it to compile is a chore, tacking on unit tests and being able to talk coherently about why injection attacks are rendered irrelevant is certainly going to be beyond your means.  If it's a certification done on a small scale, you're going to be finding an exclusive group of developers and you're going to have a high degree of confidence in any of them and as such, you've pretty much rendered the cover letter+resume then let's small talk thing moot - you're hired.Of course, this ignores a harsh reality.  If there's an economic incentive to having that certification, there will invariably be ways to game the certification.  I've interviewed (and worked with) enough incompetent but acronym-accredited developers (IBAADs, copyright MEEEEEEEE) to pay certifications little mind at all.  They're not bad, but all that's being certified is that the person's achieved some encylopediac familiarity with the terms of the field rather than a true understanding of how and when to apply them... more on that later.&lt;/p&gt; &lt;p&gt;More recently, Joel's posted about just &lt;a href="http://www.joelonsoftware.com/items/2008/01/08.html"&gt;how lame undergraduate programming courses&lt;/a&gt; are.  Did you know that people come out of school patently unprepared to do development work?  This is, frankly, SHOCKING.  That last sentence was, frankly, sarcastic.But don't despair people - software is hardly the only profession where this sort of thing is endemic.&lt;/p&gt; &lt;p&gt;I'm friends with some lawyers and I generally hear the same thing - going to law school and passing the bar is tough, but all it does is certify that you've achieved a base level of competence; they come out of the process thinking that they're ready to take on the world and are pretty immediately humbled when they realize just how unfit they are to do any lawyering.  It takes 18-24 months for a freshly bar'd lawyer to be able to do much of anything beyond researching case law, being mentored by more experienced lawyers most of the time. Doesn't this sound familiar?&lt;/p&gt; &lt;p&gt;I can't help but see the similarity with getting my degree in information systems - I graduated with good grades (cum laude, what!) and was sure that there wasn't anything I couldn't do.  I look back on my first few jobs/years of professional work and shudder at how awful of a developer I was.  I look back on code I wrote a year ago and shudder at that too.  At this point I don't think that any amount of education could fulfill all values of "rigorous and practical", let alone most of them.  This isn't to give JavaSchools a free pass or whatever, because I've interviewed people from them and their abject lack of passion for the craft is a ferocious turn-off for me.&lt;/p&gt; &lt;p&gt;In that regard, I'm with Joel.  I don't expect that people are going to step out of school ready to do it all (not gonna happen) but I do hope that they'll have been exposed to more than one way of doing things.  In my time, I brushed up (and a few hours a week for a couple of months is about all that I got in most cases) against x86 assembly, C, C++, COBOL and, yes, Java in my four years of college.  I'd like to think that I took a little something away from each of these languages about how you can make software work and the lack of LISP or some other functional language is the reason I'm learning Haskell and going through &lt;a href="http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/"&gt;The Structure and Interpretation of Computer Programs&lt;/a&gt; these days.&lt;/p&gt; &lt;p&gt;Lawyers go through as much college as I did and then 3 more years on top of that and then a certification on top of THAT and at that point, they're still so green that they require a year or two of more or less intensive mentoring to become productive.  Word on the street has it that doctors do all that, except that they're putting in hundred hour weeks while they're mentoring to boot.&lt;/p&gt; &lt;p&gt;I understand Joel and Raganwald - I wish that there was some way to certify that the developers have a shared set of values, a shared passion and a capability to rise to the task that's put in front of them, but looking for this to come from schooling or certification is, or so it would seem to me, praying for a magic bullet.&lt;/p&gt; &lt;p&gt;And even those JavaSchools that churn out mediocre developers serve their purpose - we can't all be superstars.  A great certification or four years of a great school won't turn mediocrity into a hacker god, and not every piddly project needs a superstar developer.  Certifications and education are both fine signifiers, but it'll take something more rigorous than either to signify what we're all after.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8692910019742550254?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8692910019742550254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8692910019742550254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8692910019742550254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8692910019742550254'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2008/01/meaningful-certification-is-hard.html' title='Meaningful Certification is Hard'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-3727985857595504239</id><published>2007-11-28T17:38:00.001-08:00</published><updated>2007-11-28T17:44:58.495-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>In Praise Of Being Too Clever</title><content type='html'>&lt;p&gt;Strolling into my local bank the other day to get some cash from the ATM, a little something caught my eye.  No, not the ATM what with the fuzzy, flickering screen, although the fact that my local branch in podunkville has a newer model with a nicer screen than the one in the big bank in the &lt;a href="http://en.wikipedia.org/wiki/ManchVegas"&gt;BIG CITY&lt;/a&gt; left me scratching my head.  The nameplate on someone's desk.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Director of First Impressions&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I know, and I agree with you - what the hell?  That job title's too clever by half.  But at the same time, it tickles me in all the right places.&lt;/p&gt; &lt;p&gt;It's more pleasant on the ears and brains than "ombudsman."  What kind of word is that, anyway?  No fair asking internets or dictionary.  Beats "receptionist" too (which is what they are).  For whatever reason, it speaks to a lot of things.  A company that takes itself more seriously than I do, down to the point where they've got egregious nameplates like that out in public view.&lt;/p&gt; &lt;p&gt;It got me to thinking about &lt;u&gt;Peopleware&lt;/u&gt;, the anecdote about &lt;a href="http://a.mongers.org/clueful/20020402-peopleware-blackteam"&gt;The Black Team&lt;/a&gt; in particular.  If you've never read the book and you work with software in any professional fashion, when you finish reading my drivel, go out and get it.  Seriously.&lt;/p&gt;&lt;p&gt;But anyway, it was an anecdote about a team of testers at IBM that was good at their jobs to the point where they were unafraid to loudly announce to the world &lt;em&gt;I am better at my fucking job than you are&lt;/em&gt; by dressing all in black.  It sounds corny and like a complete non-issue in the age of casual attire, but I remember watching a documentary in high school (not &lt;u&gt;Triumph of the Nerds&lt;/u&gt; but something around that time) where they interviewed OGs from IBM and they talked about how rigid the culture was, down to the point where on the first day of work, a co-worker lifted leg of the guy's pants up and critiqued the fact that he didn't have sock garters on.  Taken in that light, dressing all in black does take a pretty big pair (but then again, maybe they were all black down to the sock garters).&lt;/p&gt; &lt;p&gt;Sadly, I started wondering to myself - where's my application's director of first impressions?   For that matter, where's most software's director of first impressions?  Most software out there (the stuff I do for work included) doesn't greet you with a handshake and a smile so much as scowl at you from its office before it runs back inside and slams the door shut, hoping you didn't notice it and if something goes wrong, leaves you to fend for yourself and maybe throws you a bone with a wiki or something lame.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Why doesn't most software, most teams developing software, take what they do so seriously enough that they can get away with doing something goofy like rolling into work dressed like an execution squad when everyone else is in a regimented 3-piece suit and get away with it because they're the shit and everyone knows it?  Director of First Impressions too precious, too clever?&lt;/p&gt;&lt;p&gt;Hell no - I'm jealous.  I hope that the software I develop is too precious too.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-3727985857595504239?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/3727985857595504239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=3727985857595504239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3727985857595504239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3727985857595504239'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/11/in-praise-of-being-too-clever.html' title='In Praise Of Being Too Clever'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-2790366019365360416</id><published>2007-10-30T00:01:00.000-07:00</published><updated>2008-04-19T13:04:20.039-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='marginal utility'/><title type='text'>Marginal Utility - IsDebug for .Net 2.0</title><content type='html'>&lt;p&gt;Unfortunately for my co-workers (and especially the QA department), I play build engineer because we don't have a dedicated build engineer or even build server.  Small company, that's how it goes.&lt;/p&gt; &lt;p&gt;In recent months, I've stepped my game up.  &lt;strong&gt;Batch files, &lt;em&gt;playboy&lt;/em&gt;&lt;/strong&gt;.  I know how retarded that sounds - I was &lt;em&gt;this close&lt;/em&gt; to having Cruise Control up and running, but I got fed up with the memory footprint it left on my labtop.  It's not that trivial a matter when I can time out database calls by having a debugger up and running the same time as I have SQL Server Management Studio with a couple of windows open.  Any way you slice it, that shit is &lt;em&gt;s-a-d&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;But in the past, I wasn't quite as lazy as I am now.  Rather than spend a couple of hours cobbling together a full build script (dear me from 3 years ago - is it really so hard to Google csc.exe?), I did it all by hand from inside of Visual Studio.  Clean out the destination directory, swap from Debug mode to Release mode, compile, zip up, yadda yadda.&lt;/p&gt; &lt;p&gt;But wouldn't you know it?  It's so simple and yet I managed to screw it up.  Multiple times.  Handed QA releases that were compiled in debug mode or that had assemblies left over from debug mode and they got clued into it (because our app works slightly differently in the two modes (BY DESIGN!!!)).  How was I to know?  DLLs look like DLLs, people.&lt;/p&gt; &lt;p&gt;Eventually, I found a marvelous little utility called &lt;a href="http://www.sliver.com/dotnet/IsDebug/"&gt;IsDebug&lt;/a&gt; out on the wild internets.  Look at that!  You drag them DLLs onto it and it tells you whether they're debug mode or release mode!  Total win!&lt;/p&gt; &lt;p&gt;When I finally sat down and knocked out our app's upgrade to .Net 2.0, I was kind of bummed to find out that IsDebug didn't work anymore.  I recompiled, nothing.  Checked file properties, still not working.&lt;/p&gt; &lt;p&gt;But wait!  &lt;a href="http://jamesewelch.wordpress.com/2007/08/30/how-to-tell-if-a-net-assembly-is-debug-or-release/"&gt;Internets to the rescue again with the clue-by-four on what new properties I should be examining&lt;/a&gt;!&lt;/p&gt; &lt;p&gt;So I got Jeff's peanut butter in Jim's chocolate and here we are - IsDebug for .Net 2.0.&lt;/p&gt; &lt;p&gt;I've got &lt;a href="http://dave.c.solomon.googlepages.com/IsDebug.zip"&gt;a compiled version&lt;/a&gt; if you're lazy or don't have a compiler (I imagine this utility is especially marginal if you don't) and if you distrust stuff I write because I'm on the internet or because you know that I cut and pasted it together, there's &lt;a href="http://dave.c.solomon.googlepages.com/IsDebugSource.zip"&gt;the solution with source code&lt;/a&gt; for you too.&lt;/p&gt; &lt;p&gt;HOORAY!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-2790366019365360416?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/2790366019365360416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=2790366019365360416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2790366019365360416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2790366019365360416'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/10/marginal-utility-isdebug-for-net-20.html' title='Marginal Utility - IsDebug for .Net 2.0'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-3018530813024124101</id><published>2007-10-29T22:35:00.000-07:00</published><updated>2007-10-29T19:36:42.662-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>DebuggerStepThrough Considered Arrogant</title><content type='html'>&lt;p&gt;It happened again working with vintage code today.  I'm tracking down a problem, trying to step inside a getter on the object and all of a sudden, I've skipped over it and find myself in the next statement.&lt;/p&gt; &lt;p&gt;I'm a little confused.  I drag the execution point back up to the line I was trying to inspect.  Hit the function key to step into it, find myself skipped over it again.  What the hell?&lt;/p&gt; &lt;p&gt;So now I'm mired in a meta-problem - in order to get to the bottom of why this (the original problem) doesn't work, I have to get to the bottom of why this (stepping into the getter) doesn't work.  I look at it sideways for a little bit and nothing looks out of order, so why isn't that breakpoint being hit?  It's definitely being used.&lt;/p&gt; &lt;p&gt;Oh wait, I've seen this before.  &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdiagnosticsdebuggerstepthroughattributeclasstopic.asp"&gt;[DebuggerStepThrough]&lt;/a&gt;, the most useless code attribute on the fucking planet.  The MSDN reference fails it hard, so if you've never run into this abomination, here's what it does - tells the debugger that there's nothing of interest here, move along.&lt;/p&gt; &lt;p&gt;In a best-case scenario, &lt;a href="http://www.dotnettipoftheday.org/tips/DebuggerStepThroughAttribute.aspx"&gt;you're saving one mouse click or key press&lt;/a&gt; to step through that dumb getter.  My hero!&lt;/p&gt; &lt;p&gt;But wait!  You don't specify the attribute on a property level, you specify it on a class level.  If you're a better programmer than I am, you've managed to not screw up public exposure of private instance variables through getters and setters.  Kudos.&lt;/p&gt; &lt;p&gt;But an entire class that's bug-free?  And not causing any side effects anywhere else in the application?&lt;/p&gt; &lt;p&gt;Even if you manage to pull that miracle out of your hat, will it never have to live side-by-side with code that isn't quite on par with it?  You're still causing problems for people because your code doesn't act like everyone else's code does and that looks &lt;strong&gt;awful fucking fishy&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;So do me a favor - write that gorgeous, airtight code.  Write it as correctly as you can the first time.&lt;/p&gt; &lt;p&gt;And leave the fucking [DebuggerStepThrough] out of it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-3018530813024124101?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/3018530813024124101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=3018530813024124101' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3018530813024124101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/3018530813024124101'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/10/debuggerstepthrough-considered-arrogant.html' title='DebuggerStepThrough Considered Arrogant'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1385868553451777629</id><published>2007-10-03T23:36:00.000-07:00</published><updated>2007-10-03T20:40:32.496-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Internet Is The New COBOL</title><content type='html'>&lt;p&gt;I've been trying to quantify exactly what it is about &lt;a href="http://48klocs.blogspot.com/2007/09/software-as-service-oy-vey.html"&gt;software as a service that bugs me so much&lt;/a&gt;.  Yeah, my experiences haven't been all that winning with it so far, but I shouldn't let my anecdotes taint the promise of the paradigm, right?&lt;/p&gt; &lt;p&gt;Like Joel pointed out, computers will continue to roll out faster and with more memory, so &lt;a href="http://www.joelonsoftware.com/items/2007/09/18.html"&gt;don't sweat the micro-optimizations and build more features&lt;/a&gt;.  No way I disagree with that; Moore's Law keeps on chugging away and today's monster rig is 18 months from now's Dell.&lt;/p&gt; &lt;p&gt;But as computers inexorably get faster, more memory, bigger hard drives, our line to the outside world remains fairly constant.  Putting aside the comparatively minor problems of pretending that software standards ever worked for anything beyond the trivial (can you name one standard that gave you anything approaching wood?), SaaS seems like a plug-ugly mistake for that reason.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The success of SaaS is predicated on the use of a scarce resource, the network.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This problem was driven home in performance testing our services.  Internally, on a modest (that's a nice way of saying "hand-me-down") application server and database, we were able to push pretty good numbers through.  We're feeling good about ourselves and how it's performing, so why not point the load servers at our staging environment up on production?  It's a managed site, the hardware isn't vintage, so we're expecting to see some solid throughput.&lt;/p&gt; &lt;p&gt;We start the ramp-up, get about halfway to where we peaked in our internal testing when things start shitting the bed.  The load servers start timing out and they drop out of the test.&lt;/p&gt; &lt;p&gt;We saturated our T1.&lt;/p&gt; &lt;p&gt;Oh.  Network pipes don't double in size every 18 months?  So we set off scrambling again.  Do we order another T1 or two?  They'll take 30-45 days to be installed and then we'll be paying to have them lay fallow after we run our few days' worth of tests.  Maybe more importantly, we're not sure that our clients have any fatter pipes than we do.&lt;/p&gt; &lt;p&gt;Do we find someone with bigger pipes than we've got and tote our load machines over there for a few days?  They'll gladly let us set up shop there for a perfectly unreasonable price.  Oh.  But our connection to our back-end won't work from there so we'll need to be teleconferencing with someone on-site monitoring the servers.  That complicates things and we still don't know that performance is a problem.&lt;/p&gt; &lt;p&gt;What we do know is that the network is causing a lot of problems that we can't easily throw more hardware at.  When it comes to what a computer can do, the graph trends up and to the right.&lt;/p&gt; &lt;p&gt;When it comes to the stuff backing your service calls, how much shit can you stuff in that five pound sack?&lt;/p&gt; &lt;p&gt;XML is bloated.  Really, really bloated.  It was designed as a human-readable markup language (it's what puts the ML in XML) but basing communications protocols on it was a dubious decision, hindsight or otherwise.  Five pounds.&lt;/p&gt; &lt;p&gt;&lt;a href="http://json.org/"&gt;JSON&lt;/a&gt; is less bloated, but JSON parsers aren't as endemic as XML and business people will object because they can't juggle two acronyms at the same time and their tech guys don't know JSON but have a sneaking suspicion that it means way more work for them so they're getting doubly steered back to XML.  Six pounds.&lt;/p&gt; &lt;p&gt;You can compress the HTTP that either of them is getting shooted out over but, like JSON, not all clients are going to be able to deal with compression.  Six and a half pounds.&lt;/p&gt; &lt;p&gt;In college, professors told me that in the Bad Old Days of computing, you didn't own the computers you worked on.  You paid oodles of money to lease an IBM rig and keep it running and even then, it shipped with more hard drive space and more CPUs than were turned on at any point (over the phone line that you pay for).&lt;/p&gt; &lt;p&gt;"But professor, that's awful!  You pay all that money and you don't even get all the computer that you could be using?  And you have to pay for a phone line so their techs can dial in and turn the magic on?"&lt;/p&gt; &lt;p&gt;"No, that's a good thing.  You built your applications under constraints and when you ran into a wall because your app was running too slowly or you were running out of disk space, a call and a few hours later, magic happens and your app's running fine and disk space is no longer an issue."&lt;/p&gt; &lt;p&gt;Curiously, &lt;a href="http://www.amazon.com/gp/browse.html?node=201590011"&gt;Amazon's following IBM's lead with their S3 and EC2&lt;/a&gt; offerings.  Need more space?  Got it.  More computational power?  Bingo bango.&lt;/p&gt; &lt;p&gt;God help you if you need more bandwidth to make those calls to S3 or EC2.  Not even god can help you if your clients are running into a brick wall because they saturated their pipes calling your services.&lt;/p&gt; &lt;p&gt;Like buying IBM, basing your architecture around a decentralized network server with flexibly vast resources won't get you cockpunched for making an impossibly wrong decision by most people, but I'll still hate on you because &lt;em&gt;that's how I do&lt;/em&gt;.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;We already knew that storage space and computational power were cheap and vast.  Amazon's maybe made it moreso, but that's nothing new.&lt;/li&gt; &lt;li&gt;For what it is, the pay-as-you-go model isn't awful.  You wouldn't consider it if you could build your own disparately-hosted server farm, but you don't got the bankroll to roll like that which is why you've gone this route.&lt;br /&gt;&lt;/li&gt; &lt;li&gt;Wait a fucking second.  You knew that the network wasn't going to get any faster and you designed your application around using it extensively anyway?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Congratulations.  You've discovered the brave new frontier of decentralized internets architecture and it looks a whole lot like a fucking mainframe.&lt;/p&gt; &lt;p&gt;Web 2.0, meet Web 0.7.  Web 0.7, meet UNIVAC.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1385868553451777629?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1385868553451777629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1385868553451777629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1385868553451777629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1385868553451777629'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/10/internet-is-new-cobol.html' title='Internet Is The New COBOL'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1034857437057706266</id><published>2007-09-29T19:25:00.000-07:00</published><updated>2007-09-29T16:29:00.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oracle killed my family'/><category scheme='http://www.blogger.com/atom/ns#' term='t-file'/><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><title type='text'>Playa Hatin' on Oracle in the 2K7</title><content type='html'>&lt;p&gt;Growing up a young nerd, I spent a lot of time in my formative years on BBSes.  OK, entirely too much time that should have been spent playing in the mud and socializing with people instead of keyboards, but I digress.&lt;/p&gt; &lt;p&gt;Along with &lt;a href="http://en.wikipedia.org/wiki/BBS_door"&gt;BBS doors&lt;/a&gt; which were (are; I have a computer that supported a Telnet-connectable BBS collecting dust) awesome, I regularly found myself getting into inane flame wars about how much WINDOWS SUX LOL and MACS ARE GAME SYSTEMS ROFL to bump up my system credits so that I could spend them &lt;a href="http://www.totse.com/en/_faq/totse_faq.html#wtf"&gt;downloading t-files&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;I'm not normally one to wax nostalgic (FUCK CDS!  BRING BACK ACETATE!), but when I get &lt;a href="http://48klocs.blogspot.com/2007/05/case-for-mcmansion-architects-part-1.html"&gt;a telephone book-sized requirements document&lt;/a&gt; (or hell, one that fits on a double-sided printout), boy howdy do I start to wish for The Good Ol' Days, when Telling You How It Was was the domain of hackers.&lt;/p&gt; &lt;p&gt;I miss those precious t-files and what they connote to me.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Profanity.  Dry, cutting wit.  No mincing words, no dumbing it down for people who won't (and can't) "get it".  A pretty powerful stench of superiority, and you'd better believe that as you pore over the electrons of that tome, &lt;em&gt;you start to feel better than the assholes out there that don't know shit from shinola either&lt;/em&gt;.  Goddamn, I love those things.  I still go back and read the &lt;a href="http://www.cultdeadcow.com/cms/main.php3"&gt;Cult of the Dead Cow&lt;/a&gt; from time to time.  It can feel like a product of its time, like a zine handed off with a wink and a nod in a suburban parking lot, but it sure as hell ages better than that requirements document - pick a requirements document, any requirements document.&lt;/p&gt; &lt;p&gt;The cDc got its name from &lt;a href="http://en.wikipedia.org/wiki/Hexspeak"&gt;a little programmer joke&lt;/a&gt; (I think; please don't hack my site folks, I am 31337 and k-r4d to the bone!!!!) - people would use hexadecimal "magic numbers" to flag specific memory segments so they could find them easily.  People figured out that you could spell things with the few letters that afforded you - 0xDEADBEEF is, to my thinking, one of the swankier iterations that hackerdom mustered.&lt;/p&gt; &lt;p&gt;The fine folks at Oracle, the database company responsible for the ungodly machines required to run Oracle and the $400/hour consultants that are required to "tune" your systems so they don't run like raw ass (does raw ass run?) haven't forgotten about these magic hex codes.  I can't speak to whether they've &lt;a href="http://www.thunderguy.com/semicolon/2003/04/26/oracle-empty-string-null/"&gt;forgotten how to tell the difference between an empty string and a null one&lt;/a&gt;, but what do we care for 40 years of relational database theory?  There is only one true path to Database Enlightenment and ORACLE IS IT.  But seriously, &lt;a href="http://ola-bini.blogspot.com/2007/09/oracle-is-stupid.html"&gt;watch those fucking spaces when you work with it&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Why so bitter about Oracle when I should know better than to get all frothy about a technology that I don't use and that probably has no effect on my life?  THEY KILLED MY MOTHERFUCKING MOTHER, MAN!  No they didn't.  But I did have to deal with an Oracle salesman once (and if you've ever had to deal with an Oracle salesman, you know it isn't just once) and it left a foul taste in my mouth ever since.&lt;/p&gt; &lt;p&gt;Which is why I'm so glad to see that the way of the t-file is alive and well - this is &lt;a href="http://www.phenoelit.net/lablog/oracle.sl"&gt;some quality-ass hatin' on Oracle right here&lt;/a&gt;, folks.  A few choice quotes (but really, go read it!):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;We are talking libraries of 30 Megabytes and more linked in as well as sitting next to the binary, just in case.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;[...]&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;One can only assume that Oracle uses the Intel compiler because no other compiler would produce efficient enough code to run this behemoth of a binary in acceptable speed.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;[...]&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;And we would like to welcome Oracle Corp. in the year 2007, the century of highly advanced, mixed-case passwords.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;When I was young, after getting over wanting to be an astronaut and paleontologist, I wanted to be a guy who dug deep into the cruft of software and systems, ripped the secrets out of them and brought them back to the world.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;I never became that guy (and doubt I ever will because I spend too much time playing video games and I'm not that smart), but I am glad to see that there are people out there hacking away and still producing quality t-files.  That they're straight hatin' on Oracle is just a triple word bonus.&lt;/p&gt; &lt;p&gt;Now if you'll excuse me, I have to start praying that &lt;em&gt;no one ever looks at my code ever&lt;/em&gt; because I'd probably break down sobbing like a big stupid baby if it ever received that kind of brutal scrutiny.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1034857437057706266?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1034857437057706266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1034857437057706266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1034857437057706266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1034857437057706266'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/09/playa-hatin-on-oracle-in-2k7.html' title='Playa Hatin&apos; on Oracle in the 2K7'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-247885269177453968</id><published>2007-09-28T19:54:00.000-07:00</published><updated>2007-09-29T11:15:38.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='interface'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Software as a Service - Oy Vey</title><content type='html'>&lt;p&gt;Software as a service (SaaS), we need to talk.&lt;/p&gt; &lt;p&gt;You had so much promise.  Mashups!  Loose coupling!  And other buzzwords/phrases that architects, CIOs and developers could somehow all get behind.  Tangentially, does anyone still say "the network is the computer"?&lt;/p&gt; &lt;p&gt;I guess it was a pretty cool idea.  Rather than having to worry about the boundaries between Widgets Foo and Bar, you just wave your stupid hands, utter things like "SOAP!" and "XML-RPC!!" and presto!  Those fuckers are &lt;strong&gt;working together perfectly&lt;/strong&gt; because of &lt;em&gt;the magic of standards-based communications&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;No more fugly COM calls.  CORBA?  It's dead to us.  What's old (piping text files between widgets, Unix-style) is new again!  Hooray XML!&lt;/p&gt; &lt;p&gt;It's so simple, how can this possibly go wrong?&lt;/p&gt; &lt;p&gt;Glad you asked.  You produce a service.  The person on the other end - do they know how to consume the service?  Do they take into account things like "am I trying to read this file before you've finished streaming it over the tubes to me?"  That web services definition that you published - are they really adhering to it?  Will those line breaks you put in to make it readable throw a wrench in the works (oh if only I saved that godforsaken e-mail chain to forward along to The Daily WTF).&lt;/p&gt; &lt;p&gt;Let me try putting that another way - you're selling your software as a web service.  What happens when, for any reason, people find themselves unable to consume it?  If you're like me, you'd like to curse at them for their brazen incompetence and write them off.  If you're also like me, you realize pretty quickly that you're cannibalizing your own bottom line by writing off these clueless retards in DRAMATIC FASHION because they're the ones that are paying for your stupid service.&lt;/p&gt; &lt;p&gt;Their problem suddenly becomes your problem.  Managing one project at a time is enough of a nightmare; now, in addition to the one you're only barely managing, it's your job to asymptotically manage another.&lt;/p&gt; &lt;p&gt;But I don't mean to exclusively hate on SaaS - this problem extends, in one form or another, to any product that you sell.  At the point that it leaves your hands, no matter how fully-rendered, it enters the payers' hands and no matter how drop-dead simple, how intuitive the interface, someone is going to fuck it up and then your headaches begin.&lt;/p&gt; &lt;p&gt;Just that when the inevitable fuck ups happen to be piped over SSL with proxy servers and firewalls and misbehaving routers between points A and B, life seems a little less rosy.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-247885269177453968?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/247885269177453968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=247885269177453968' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/247885269177453968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/247885269177453968'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/09/software-as-service-oy-vey.html' title='Software as a Service - Oy Vey'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5126009777631322156</id><published>2007-09-17T21:00:00.000-07:00</published><updated>2007-09-18T07:30:37.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Zen slapped!</title><content type='html'>It wasn't a moment of clarity or anything else, it was a moment when what made sense no longer did.  I have the same problem with words - for a couple of years, "will" just &lt;span style="font-style: italic;"&gt;didn't look right&lt;/span&gt; to me; I had this nagging feeling that I'd spelled it wrong when I hadn't.&lt;br /&gt;And in a roundabout way, having read a &lt;a href="http://weblog.raganwald.com/2007/09/codedata-separation-and-encapsulation.html"&gt;meta-post on what Steve Yegge has to say today about objects or something&lt;/a&gt; (my attention span's too short to find out), suddenly the canon of "objects for your business logic, databases for your data" seems to have been proffered by a madman.&lt;br /&gt;At first I was trying to figure out exactly what encapsulation is being broken - as long as objects are responsible for their own persistence (when asked nicely) and retrieval (when supplied a morsel of information), where is the disjoint, right?&lt;br /&gt;But wait a second.  What's the "real" object here?  We've got business objects and they can be composites of other business objects.  But we don't have much to do with our business objects without instantiating them and without eventually persisting them somewhere... at which point, we've got another instance of an object, only now in relational form.&lt;br /&gt;That relational "object" can itself be a composite of sundry other "objects" (tables), unless you're the sort that just tacks another varchar(8000) column on your God Table and calls it a day (and I promise to make fangless threats to beat you to death with Codd's corpse if I ever have to support such a mythical beast).&lt;br /&gt;And tying these two disparate, equally valid (depending on who you ask and when), objects together is what amounts to a domain-specific language (SQL) so that you can get these two different domain objects talking to one another.&lt;br /&gt;This feels unnatural to me and I'm not left wondering why things don't work but rather in awe of the fact that they work in spite of being tied together with duct tape and zip ties.&lt;br /&gt;Thankfully, Giles Bowkett came along and dropped a pithy &lt;blockquote&gt;oodbs ftw&lt;/blockquote&gt; in the mix and I was slapped back into... coherence?&lt;br /&gt;I've never bought into object-oriented databases because I've never taken the time to wrap my head around them (chicken and egg, that).  I understand relational databases - I've long since internalized normal forms and I understand how they help me to enforce data integrity and are generally pretty performant (disk size, memory, speed) ways to persist data.&lt;br /&gt;Even if you take size/memory/speed out of the equation, there's a little matter of people making mistakes - I've yet to come up with an object design that worked out of the gate.  When I bone it (and I just about always do), it means tacking on more columns, more tables.  The stored procedure interface then (probably) changes and the upstream object (and their calling objects) which is all kind of ungainly, but all the "legacy" data is still there for the taking.  When you refactor an OODB, what happens?  I mean, it was persisting an old version of your object, right?  Is this something you have to take into account manually somehow (I imagine so)?  I'm scared.&lt;br /&gt;Model/view/controller, I'm sorry I doubted you honey.  But you have to admit, you are kind of freakish when you take a step back and think about it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5126009777631322156?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5126009777631322156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5126009777631322156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5126009777631322156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5126009777631322156'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/09/zen-slapped.html' title='Zen slapped!'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4494795870562111789</id><published>2007-09-14T20:53:00.000-07:00</published><updated>2007-09-14T17:49:33.186-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>What are you good at?</title><content type='html'>It's been a confluence of things that's left this question tingling in my head, begging me to ask it to just about everyone at work.&lt;br /&gt;Work's been a firefight - stuff is blowing up and I've been asked to put down what I was working on to help look into it.  It's technology that I don't know, code that I don't yet have a mental picture of and unknowns on all sides (our app, our hosting environment, their app, their test methodology, yadda yadda).&lt;br /&gt;It's all finger-pointing and scrambling through the mismanagement playbook.  Regularly changing priorities.  Micromanagement on a level I didn't think was possible.  Scrambling to find consultants who can "help" (from the same consulting company that built a large portion of the app, naturally) and get them put on &lt;span style="font-style: italic;"&gt;hot standby&lt;/span&gt; even though we haven't been able to pin the problem down yet.  More people from outside the organization being brought in to help micromanage.  Scheduling people to test round-the-clock, generally frazzled nerves all around.&lt;br /&gt;At some point I took a step back and started to wonder how we ended up in this mess in the first place.  It sort of dawned on me that up the food chain, someone failed to ask a simple question that could have saved us all a bunch of time.&lt;br /&gt;&lt;blockquote&gt;What are we good at?&lt;/blockquote&gt;This really is as simple as it sounds.  If you're heading up a company, you think in terms of "core competencies."  (That's a real term, right?)&lt;br /&gt;You don't over-extend yourself.  I can grill a mean steak and I can brew a ferocious cup of coffee, but at the end of the day I'm not going to try to write a cookbook because that'd be even more unreadable than this is.&lt;br /&gt;Unfortunately, that's sort of what the situation that we're in feels like.  Rather than define and focus on what products we felt we could successfully accomplish in a set period of time, we were told what we needed to get done in that same period of time.&lt;br /&gt;I can see how it's a risky sell - "rather than over-extend my people and producing n working products, I'd like to focus in and produce n-2 pretty high-quality products that I have confidence that they'll be able to build, test and release."  &lt;span style="font-style: italic;"&gt;You're talking about setting us back 2 products that we could be selling.  &lt;span style="font-weight: bold;"&gt;Are you out of your mind?&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;As a strict value prop (that's "value proposition" for those of you not in the know, another vaguely business term that I'm sure I fucked up using) the value of quality isn't easy to wrap your head around.  McDonald's doesn't make the highest quality hamburger but they make bank, right?&lt;br /&gt;Right - and when they've failed to ask themselves what they're good at, the market's reminded them.  What ever happened to the gourmet menu that I remember hearing about 15 years ago?  The pizzas?  The steaks?  The lobster rolls (I've heard they have them in New England but it's not like I've gone looking for them because what the shit so maybe they still have them?)?  They weren't good at them.  They spent a lot of time and money developing them and they ultimately ate those development costs and pulled them off the shelves.&lt;br /&gt;What works for a corporation doesn't work for a developer.&lt;br /&gt;When I got to thinking about what makes an object work for me, something one of my first computer science teachers told me when looking over my code came back and stuck in my head.  Paraphrasing what he told me...&lt;br /&gt;&lt;blockquote&gt;You should be able to describe a function in one sentence.  Furthermore, when it's time for you to describe that function, the word "and" should not be in that sentence.  There should be no semi-colons, no subjugate phrases, no hyphens.  If you find yourself using the word "and" to describe your function, you're not describing a function, you're describing two functions.&lt;/blockquote&gt;So I discovered the joy of decomposing functions.  I didn't get down and dirty by declaring every variable as final.  I'm by no means writing functional code and I slip all too often and my functions do two things, but I try to refactor them when I'm able to admit to myself that yeah, that really is doing multiple things.&lt;br /&gt;The code behind the application that's sometimes working like a champ, other times shitting all over the floor... not so much.  Giant blocks of code.  Twisty turny, deeply nested if blocks.  Classes dedicated to re-doing functionality that the .Net framework had built in (if only they had asked Google).&lt;br /&gt;I want to give the codebase one last hug before I put it out of its misery - when I look at it and ask it "what are you good at?", it sighs heavily and shakes its head.  It doesn't have to say anything - that look it gives me is all I need to know.  I've seen it before, and I'll see it again.  Finally it says in a weak little voice, "I'm good at doing whatever they wanted me to do today.  I think.  What was I doing yesterday?  I'm not even sure what I'm doing here."&lt;br /&gt;It's not its fault.  It's not their fault.  Someone should have asked "what are we good at?" and someone should have responded "not this" and that should have been that.&lt;br /&gt;We were given this weekend off (not that wild horses were going to drag me in for another consecutive day of hair-pulling).  Management is good at giving us what we shouldn't even have to ask for.  Maybe next time they'll learn to ask us what we can give them instead and we can produce one or two quality products rather than a bunch of garbage and save everyone a lot of agony.&lt;br /&gt;Wishful thinking, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4494795870562111789?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4494795870562111789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4494795870562111789' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4494795870562111789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4494795870562111789'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/09/what-are-you-good-at.html' title='What are you good at?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5998632117076022430</id><published>2007-09-12T21:41:00.000-07:00</published><updated>2007-09-12T21:41:55.307-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The Joy of Recursion</title><content type='html'>I read &lt;a href="http://www.math.chalmers.se/%7Erjmh/Papers/whyfp.html"&gt;Why Functional Programming Matters&lt;/a&gt; because &lt;a href="http://weblog.raganwald.com/2007/03/why-why-functional-programming-matters.html"&gt;Raganwald told me to&lt;/a&gt; and he's about a jillion times smarter than I am.  It was an equally frustrating and enlightening experience for me, but boy howdy has it ever gotten my brain wheels spinning again.&lt;br /&gt;For too long, I think I've forgotten why I got into programming - there's a terrifying amount of stuff to learn.  As of late, I've settled into a rut (however productive) of kind of &lt;a href="http://48klocs.blogspot.com/2007/08/sometimes-foresight-is-2020-too.html"&gt;reflexively seeing every problem in terms of objects for the business logic and a relational database to persist the data&lt;/a&gt;.  It's good and bad - I can make it work, but there's that nagging little voice in the back of my head wondering if I could have done it differently (and the slightly louder voice reminding me to ignore that voice and Do The Simplest Thing That Could Possibly Work and map and filter aren't necessarily it (for me (right now))).&lt;br /&gt;Back in  Ye Good Olde Days, I really got a kick out of programming.  Moving at my own pace, figuring out what worked and what didn't at my own pace... what could be better?  One of the things I figured out back then was &lt;span style="font-style: italic;"&gt;recursion sucks and no one should use it ever&lt;/span&gt;.  Asking me why that got stuck in my head would be as productive as asking why I didn't go outside, it's a beautiful day.  &lt;span style="font-weight: bold;"&gt;Computer's inside.&lt;/span&gt;  But the idea that I could get through life with nothing but recursion did stick with me for a few years.  In my defense, I had a lot of awful ideas about how programming should and shouldn't work back then.  Some things never change, I guess.&lt;br /&gt;After my limited experience in college with Lisp, I chalked it (Lisp/functional programming) up as something destined to die in the halls of academia.  After all, object oriented programming has conquered in the marketplace of ideas, right?  Well, yeah.&lt;br /&gt;But then again, there's a not-so-small matter of The Multicore Era.  I've done my penance with threading and there was little with it that came easy.  I still think that there must be companies out there working on C++/Java/.Net compilers that hide the ugliness of working with multiple CPUs/cores, but curiously, the same machinations you go through to make your object oriented code play nice with multiple processors make it start to look... almost functional.&lt;br /&gt;Why FP Matters did a good job of opening my eyes and stretching out corners of my brain that have laid fallow for too long, but it's aggravating.  For every idea I can almost wrap my head around, there's a dozen that I can see on the periphery slipping away from me.&lt;br /&gt;I don't want to let those dozens slip away from me quite yet.  I'm now slowly working my way through &lt;a href="http://en.wikibooks.org/wiki/Haskell/YAHT"&gt;YAHT (Yet Another Haskell Tutorial, a better read than the name would have you believe, honest)&lt;/a&gt; and rediscovering my inner child.  I'm inept in Haskell - functional programming's still completely foreign to me.  The syntax feels awkward.  I'm not even illiterate in this and I can still feel myself trying to translate OO to FP.&lt;br /&gt;But there's something to be said for rediscovering the Fibonacci sequence and factorial functions in a new light.  I shouldn't be beaming this much about a dead academic language.  I shouldn't seriously be considering reading The Structure and Interpretation of Computer Programming over the winter.  I should maybe be making friends with a nice language like F# that I could do something with.  &lt;span style="font-style: italic;"&gt;How will I ever make money with this?&lt;/span&gt;&lt;br /&gt;There's no real logic to it, I just feel like the time's right to play with it (don't I have a Wii for that?) and I'm enjoying it.  My inner child's even beginning to make peace with recursion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5998632117076022430?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5998632117076022430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5998632117076022430' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5998632117076022430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5998632117076022430'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/09/joy-of-recursion.html' title='The Joy of Recursion'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4220158838665144617</id><published>2007-08-27T22:41:00.000-07:00</published><updated>2007-08-27T19:42:25.261-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Am I this clueless about the business?</title><content type='html'>To give a little background, I work in the health care insurance industry.  Grand.&lt;br /&gt;So today we had an exec in from the home office to give a little pep talk or something.  Or acknowledge that &lt;span style="font-style: italic;"&gt;important people&lt;/span&gt; are, in fact, aware that we exist.  I'm not entirely sure what the point of it was.&lt;br /&gt;Amidst the flow of coached company lines, it was the unguarded moments that caught me.&lt;br /&gt;One of the thingies that we develop lets people "choose" the benefits they "want."  Apparently, customer satisfaction ("Customer Sat" for those of us in the biz)  with their benefits is reasonably high enough with people who have gone through and used the thing.&lt;br /&gt;Which leads to faux pas number one -  after reinforcing that people are satisfied with our product, he joked about how unsatisfied employees are with our benefits.  This is no joke - my benefits have gotten worse in every way I can think of since getting hired once upon a time.  More expensive, less covered, more hassles.&lt;br /&gt;But somehow, giving people more choices about their health care makes them happier about what they end up with.  You'll hear it referred to as "consumerism," the great hope of the health care insurance industry and if you're like me, you'll somehow find yourself pining for the "bad old" days of HMOs.  And they were bad, but the new high-deductible garbage foisted on us is worse.  But more choices makes it better.&lt;br /&gt;To prove this, faux pas number two.  Guy's got a daughter headed off to college.  She's an art major and they wanted to make sure she had a laptop for school.  What sort of computer do you think they got her?  You don't have to be &lt;a href="http://en.wikipedia.org/wiki/Miss_Cleo"&gt;Miss Cleo&lt;/a&gt; to guess "an Apple" and be right.  But all the choices - how big a screen, how fast a processor, yadda yadda apparently made him happier about the choice.&lt;br /&gt;All I could and can think is  - "yeah, but they fooled you into fooling yourself into thinking there was a choice."  The only choice was "Apple" - the rest of it was window dressing.  They could have offered a single make and model and he'd have bought it because they deliver a product people love (because the people that work for Apple believe in the product that they deliver (because it's a good product that people love (ad absurdum))).&lt;br /&gt;Furthermore, Apple might not be around to sell jack shit if it weren't for the iPod, which doesn't give you a whole lot in the way of those choices that we apparently demand.  A bigger drive, different colors.  Not much in the way of choices.  When it was first released, it was dead in the water because it didn't have features that other MP3 players had.  The fact that no one really wanted or needed or used these other features was irrelevant - the iPod just didn't have them.  Suckers.&lt;br /&gt;&lt;blockquote&gt;"People don't want to buy a quarter-inch drill. They want a quarter-inch hole!"&lt;br /&gt; - &lt;a href="http://hbswk.hbs.edu/item/5170.html"&gt;Theodore Levitt&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;I don't buy the notion that people want to do a whole lot of choosing their health care benefits.  If they're like me, all they want to know is that when shit happens, I'm not going bankrupt.&lt;br /&gt;Four years ago (when we had insurance from An Insurance Company I Am Not Employed By), I had a migraine that lasted five days.  I finally broke down and went to the hospital - they CAT scanned me, found an abnormality, had me back in in a few days for an MRI.  Nothing wrong with it, but I should get it checked out regularly just to make sure.&lt;br /&gt;I think I was out all of $10.  I was happy with my insurance.&lt;br /&gt;Since getting hit by the truck and getting deluged with mail, I have no such confidence in my health care.  The little form letter I got after we got bought out letting me know that I just need to double-check with them before I got an MRI doesn't help matters in that confidence regard.&lt;br /&gt;I see the same godawful tyranny of the amateur in financial planning - I suspect that folks in the industry there are able to trot out study after study proving that people are inexplicably  (to me, at least) more satisfied with planning their own 401K.  I hate it.  Hate it.  I don't know this mutual fund from that index fund.  What do I know?  That I want to retire some day (the sooner, the better) and be able to do it comfortably.&lt;br /&gt;What do I want from health care?  To know that if shit happens, I'm covered.  I do not want to know in network, out of network, deductible, copay, blah blah blah.  More information leaves me less satisfied.&lt;br /&gt;I feel like we're being set to work building shadows.  People are monstrously unsatisfied with their health care and a little novelty makes people momentarily happier about it (at least on a survey card) so more novelty will make them even more satisfied!  And more information about it (one of the cornerstones of "consumerism" is bombarding people with information that's goddamned near impossible to parse) will make them happier!&lt;br /&gt;I need that quarter inch hole.  If there's any question at all about how I procure that quarter inch hole, if you make me work to figure out what drill &lt;span style="font-style: italic;"&gt;suits my lifestyle&lt;/span&gt;, you run the very real risk of me finding out that someone else provides a better, faster, cheaper, stronger drill bit.&lt;br /&gt;I'd like to be more Apple, ignoring what people say they like and giving people what they want and less chasing ghosts on customer satisfaction cards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4220158838665144617?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4220158838665144617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4220158838665144617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4220158838665144617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4220158838665144617'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/08/am-i-this-clueless-about-business.html' title='Am I this clueless about the business?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7243483342752744354</id><published>2007-08-20T19:34:00.000-07:00</published><updated>2007-08-20T16:39:37.667-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Management Jeopardy</title><content type='html'>&lt;p&gt;"I'll take Unsane At Any Speed for $1000, &lt;a href="http://www.google.com/search?q=douchebag"&gt;Alex&lt;/a&gt;."&lt;/p&gt;"This defies rational explanation and is a sure-fire hint that you're working at the wrong place.  Yes, Dave."&lt;br /&gt;&lt;p&gt;"What is a four hour meeting that starts at 6 PM?"&lt;/p&gt;I'm not smart enough to make this up.  I'm pretty sure that meetings that long are in violation of the Geneva Convention to begin with, but having it start well after working hours end on top of that?&lt;br /&gt;&lt;p&gt;To clear up some mitigating factors that weren't...&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We do not have any off-shore workers, so it's not a matter of having to figure out a way to meet with people halfway around the globe.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We are not a huge company.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;I can't keep track given all the resignations and hirings, but we've got about 40 employees.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We are owned by a (much) bigger company.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We have one main point of contact with this bigger company (most of the time) who was involved in it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Adding injury to injury, some of the people in the meeting had an 8 AM meeting earlier that day.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;It wasn't a matter of showing up late in the day for a late meeting.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;No time's being compensated for this.  There was no half day at the end of that tunnel.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;In as much of its defense as I can raise, I wasn't in this meeting and the people who were in it say that they really got stuff done.  If I was in there, I'd be telling myself that to save my sanity too, so who knows.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Actually, there would be no need to save my sanity.  Nobody's going to pay me the kind of money I'd expect to be paid for the insane brand of job where the very idea of a meeting from 6 PM to 10 PM isn't immediately laughed out of the building.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This is, easily, the worst solution for the "we have too many meetings and not enough hours in the day to get all the particulars together" problem that I've ever seen.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7243483342752744354?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7243483342752744354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7243483342752744354' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7243483342752744354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7243483342752744354'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/08/management-jeopardy.html' title='Management Jeopardy'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8117694960921974771</id><published>2007-08-17T19:18:00.000-07:00</published><updated>2007-08-17T16:19:56.662-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='cycling'/><title type='text'>Sometimes Foresight is 20/20, Too</title><content type='html'>I keep trying to come up with really great, really kick-ass ideas for programs that I can sit down and knock out.  I want to find that itch that I can conceivably scratch.&lt;br /&gt;I obviously haven't had any.&lt;br /&gt;Every now and then, someone I know will come to me with a "wouldn't it be great if..." idea that they've got, but there's two problems with them.  OK, one problem.  They're invariably not that great because if they were, I'd have jumped all over it because it felt like that great of an idea and I wouldn't be typing to an empty audience, I'd be dictating this in front of a sold-out crowd at Madison Square Garden because &lt;span style="font-style: italic;"&gt;I paid for them to watch me sit here and dictate this tripe to my butler's butler&lt;/span&gt; after having built whatever that great idea was.&lt;br /&gt;The second, obviously subjugate, problem there is that I haven't had any great software ideas (of my own or lent to me) that got my juices flowing.  I haven't had much more than ideas for the sake of ideas.&lt;br /&gt;Until one fateful day a few weeks ago.  I'd gotten back from work and was out on a bike ride to clear my head and stretch my legs out.  It was a nice enough late afternoon and climbing the hill, I started to think back to all the silly little programs I wrote when I was a young lad dabbling in BASIC and PASCAL.  Terrible "RPG"s and the sort.  Cut-rate Ultima Is, minus, well.  Everything that would make them playable.&lt;br /&gt;It suddenly became obvious - why don't I write a &lt;a href="http://en.wikipedia.org/wiki/Roguelike"&gt;roguelike&lt;/a&gt; in .Net?  Since then, I've been kicking around the idea and it's only gotten bigger and, well, dumber.  As Google will tell you, the very idea of a roguelike in .Net is a dumb one to begin with.  I haven't even started so I couldn't tell you why.&lt;br /&gt;Compounding the shaky base I'd apparently be starting with, some truly awful thoughts have gone through my head.&lt;br /&gt;&lt;blockquote&gt;"Hey, I could write a flexible MVC implementation so that it could be presented by either a web interface or a BBS door!"&lt;/blockquote&gt;Yes, another filthy childish love of mine is olde tyme BBSes and door games.  I've tried to come up with a good idea for a door game to produce, but no dice there either.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;"Hmm.  Since it's online, I could make it multiplayer.  I remember reading some design documents for Multihack; how will I handle surreal time?  If there's two people on the same dungeon at the same time, how do I handle the dungeon-moves-when-you-say-so aspect of it?  Can I fix this?"&lt;/blockquote&gt;Multihack was the multiplayer version of &lt;a href="http://www.nethack.org/"&gt;Nethack&lt;/a&gt; that never quite saw the light of day.  If you've never played a roguelike, the game world doesn't advance until you make your move.  You can take a second or a week to make that next move.  This presents obvious problems when more than one person inhabits the same level and Player A wants to move NOW while Player B wants to take 10 or 20 minutes to decide whether to read a cursed scroll of levitation or enscribe Elbereth or whatever.  Oh yeah, I went there.&lt;br /&gt;&lt;blockquote&gt;"How do I persist the levels?  Hmm.  Oh, I know - this feels like a pretty relational data model that I'm working with.  I'll just install SQL Server."&lt;/blockquote&gt;At that point, a bigger, louder voice in my head screamed "SQL Server for a fucking roguelike?  What the shit are you thinking?"  Thankfully, foresight finally reared its beautiful head.&lt;br /&gt;If I may, a few words in my defense.&lt;br /&gt;Day in, day out, I write database-backed web applications.  I take detours to write "thick" WinForms apps here and there and then multithread them based off of need rather than just because I can (honest) so I've got a really solid comfort level when it comes to, well, ASP.Net up front, C# codebehinds and middleware and SQL Server backing it all.&lt;br /&gt;That said, I recognize that it's more than OK to step out of your comfort zone from time to time.  It wasn't comfortable when I took a step back and started to see that what I was trying to pass off as object-oriented code was, being generous, marginally better procedural code with some trappings of objects tacked on as an afterthought.  I'd gotten comfortable writing that way as a student and hadn't progressed much since (and coworkers who'd been there before me and had more experience were writing the same).&lt;br /&gt;At a certain point that felt logical to me, I stopped with the parameteritis and the basically stateless objects and started writing object-oriented code they way that I thought it should be written, trying to take care to think about what it was doing and how it would be used now (rather than building things in &lt;span style="font-style: italic;"&gt;because you never know&lt;/span&gt;), but I think that I'm a better programmer and my software's better and easier to maintain because of it.&lt;br /&gt;It wasn't comfortable when I got started and it was slow going at first, but I'm happy with where I've ended up.&lt;br /&gt;Now that I find myself at the top of a mountain again, do I try to convince myself that I've climbed to the peak of the world or do I take a look around and see that there are other mountains that I should climb?&lt;br /&gt;My class diagrams (which look every bit like a socially inept teenager scribbled them down) for my roguelike can sit in a pile on my desk for a while.  A database for a roguelike feels so impossibly wrong that I can appreciate the fact that it's time for me to stretch a bit and tighten up my laces because I've got some climbing to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8117694960921974771?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8117694960921974771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8117694960921974771' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8117694960921974771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8117694960921974771'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/08/sometimes-foresight-is-2020-too.html' title='Sometimes Foresight is 20/20, Too'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-16024176512496628</id><published>2007-08-05T04:15:00.001-07:00</published><updated>2007-08-05T20:11:53.892-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cycling'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Triathlons are hard.</title><content type='html'>&lt;p&gt;I &lt;strike&gt;competed&lt;/strike&gt; took part in my first-ever triathlon yesterday, the &lt;a href="http://www.franconiasports.com/about_topnotch_triathlon.html"&gt;Top Notch Triathlon&lt;/a&gt; up in Franconia, NH.&lt;/p&gt; &lt;p&gt;It sounded so easy - 6.5 miles of biking (3.5 on paved roads, 3 on trails), followed by a half mile swim, then a 2.5 mile run/hike.  I'm a fat lazy guy and I'm pretty sure that I could do that in my sleep.&lt;/p&gt; &lt;p&gt;And then I found out that there's a 1040 vertical foot rise in the cycling part.  And 2280 more in the hike.  (Thankfully, the swim was pretty level (har har))  I probably should have looked into that before I went out there.&lt;/p&gt; &lt;p&gt;I didn't really have much in the way of goals for the triathlon.  You may not have known this about me if you skimmed above, but I'm fat and lazy and really all I did to prepare for this was ride my sweet new bike a lot.  Unfortunately, that was about all the preparation I did for the race.&lt;/p&gt; &lt;p&gt;I took a look at the numbers (before I noticed the vertical climb advertised) and I wasn't even going to bother swimming in preparation because I'm fat and fat floats and I could swim all day when I was 10 years old.  I wasn't going to run because I don't like to run all that much anymore.  The little running I did didn't help, but I'm glad I got a few laps in swimming before I got out in the lake so I wasn't in for such a huge slow surprise.&lt;/p&gt; &lt;p&gt;The second-biggest surprise of the day was how poorly I did biking - I started at the back of the second pack and was &lt;em&gt;passing suckers left and right&lt;/em&gt; on the road portion.  I was keeping a pretty leisurely pace - I knew that it was only 6.5 miles, but I also knew that I didn't want to burn myself out cycling.  The trail ride was a different story.&lt;/p&gt; &lt;p&gt;I've never ridden in packs off-road.  I've ridden with two or three people, but mostly on fire roads or where we had the luxury of spacing out well enough to not interfere with one another, and with people at about the same skill level as me.  The trails we were on were double-track in some parts, but mostly single-track with roots and rocks and muck on the other side for passing lanes (where there were any), which meant you had to work considerably harder to pass people.  I was trying to conserve energy, so I didn't do a whole lot of passing.&lt;/p&gt; &lt;p&gt;Except I sort of had to, because there were people who were really slow and really unsteady out there.  I was not prepared for people to be slowing down for every mid-sized rock, every root, every mud bank out there and had to dab a couple of times and fell once when someone abruptly braked and cut left across my front wheel for no good reason.  It was tough on me because riding alone, I'm used to keeping up the cadence that I want to keep up and go the speed I like.  Out here, I was constricted to keep up an awkward cadence and go slower than I would have liked - it wasn't until well into it (maybe a mile left) that the light bulb went on above my head and I realized "hey, maybe I should shift up to an easier gear to keep up the cadence I want even at this pretty crawling pace" and things got easier at that point.&lt;/p&gt; &lt;p&gt;Then on to the swimming!  I knew I'd be slow because I'm in such awful shape that I can't even maintain a freestyle for more than a few hundred yards.  Can I blame that one on the broken collarbone and ribs circa 16 months ago even though they don't hurt me?  The water was 70 degrees and felt pretty damned nice to get into right after I got off my bike.  I was going as slow as I expected to go, but I wasn't gassed by the time I got out of the water, so I figured I was doing pretty OK.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_o0DdI8cNKGU/RraNPevWU6I/AAAAAAAAAAM/8UNdU2QHP6c/s1600-h/DSC_0046.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_o0DdI8cNKGU/RraNPevWU6I/AAAAAAAAAAM/8UNdU2QHP6c/s320/DSC_0046.JPG" alt="" id="BLOGGER_PHOTO_ID_5095415325505508258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I'm not in as much pain as I look here, just squeegeeing my hair and trying to keep the water from getting in my eyes/contacts.  OK, maybe I am as tired as I look.  Thankfully, there are no 10 year old girls racing ahead of me in this picture.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;I expected there to be some change station where I could get my other change of clothes on for the third leg but there wasn't, so I just toweled off a little, dried my feet and put on my socks, strapped on my camelbak, and started up the mountain in my bike shorts.  For anyone that was stuck behind me, I'm so very sorry about that.&lt;/p&gt; &lt;p&gt;I'd run a whopping 10 miles in preparation for this, so I figured I'd run as far up the mountain as I could.  Once I got a look at the first hill you take off up and its vertical incline, that thought went straight out the window.&lt;/p&gt; &lt;p&gt;The hike was, well.  Kind of brutal.  At parts it was sand and loose rocks, not a winning combination by any stretch of the imagination.  Other parts it was ledge (exposed slabs of rock).  All of it was steep, steep, steep.  There were a few short legs where it flattened out or had a slight decline, but mostly it was uphill and then some.  The early part of it wasn't that bad - I wasn't trying to sprint up there, so I slowed down a bit and chatted with a few people on the way up and that was alright.&lt;/p&gt; &lt;p&gt;By the time I'd made it to the first water station, I was wondering how much further it was.  By the time I passed the second water station, I was worrying how much further it was because I was starting to get worried.  There were other people stopping to take a break from time to time and I wanted to as well, but my legs were starting to tighten up pretty bad and I was worried that if I stopped, I'd cramp up and make my life a hell of a lot tougher.&lt;/p&gt; &lt;p&gt;In my head before the race, no sweat.  I'll run as much as I can, hike the rest and sprint to the finish.  There was no sprint to the finish.  I grabbed a bottle of whatever bottled water they were handing out on the finish line (even though I still had a good 30 oz. of water in my camelbak) because my brain was fairly mush at that point.  As in - me even dumber than usual which is hard to compute.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_o0DdI8cNKGU/RraNWevWU7I/AAAAAAAAAAU/0HfaFk4CwT4/s1600-h/DSC_0074.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_o0DdI8cNKGU/RraNWevWU7I/AAAAAAAAAAU/0HfaFk4CwT4/s320/DSC_0074.JPG" alt="" id="BLOGGER_PHOTO_ID_5095415445764592562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I am as tired and confused as I look in this picture.  And then some.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The cramps were still creeping up on me, so I stood in the shade for a few minutes sipping my water and started to feel better, so we took the tram back down the mountain to go collect my bike and head back to the starting point so I could change out of my bike shorts and sweaty shirt and check my final time. &lt;p&gt;I scatterbrained the post-race tie-up activities multiple times, so it was multiple trips back there and eventually they had my time posted - 2 hours, 4 minutes.  I finished 195th (198th? again, scatterbrained) out of, uh.  I don't know how many people.  My number was 318, so I'm employing my advanced mathematics training and figure that I finished in the top 2/3rds of the race which is a &lt;strong&gt;gentleman's pass&lt;/strong&gt; any way you slice it.  I remember that I was 178th in the biking and 20th out of 22 in my age division (WHAT ABOUT BMI DIVISION, BIGOTS?), neither of which I'm really proud of.  The biking especially I'd like to make excuses for - I didn't know how hard I could push, the cadence thing throwing me for a loop, yadda yadda, but whatever.  I wasn't competing, it just seemed like something fun to do.  And it was.&lt;/p&gt; &lt;p&gt;Except for that goddamned hike.&lt;/p&gt;&lt;p&gt;Now that I've swam a lake and climbed a mountain, picking up functional programming should be a piece of cake, amiritefolks?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-16024176512496628?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/16024176512496628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=16024176512496628' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/16024176512496628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/16024176512496628'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/08/triathlons-are-hard.html' title='Triathlons are hard.'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_o0DdI8cNKGU/RraNPevWU6I/AAAAAAAAAAM/8UNdU2QHP6c/s72-c/DSC_0046.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-2748676687145204731</id><published>2007-07-24T21:14:00.000-07:00</published><updated>2007-07-27T22:07:25.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='requirements documents'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Software development - the journalism model</title><content type='html'>&lt;p&gt;You probably don't know this about me, but I've studied journalism &lt;em&gt;extensively&lt;/em&gt;.  Back in third grade (for my vast international readership, that's the grade level you're in when you're ~9 years old), I learned journalism well enough that I think I wrote an article or two for my school paper.  Maybe I even &lt;em&gt;edited&lt;/em&gt; an edition of it - obviously, my journalistic credentials can't be called into question.&lt;/p&gt; &lt;p&gt;We learned that the essence of journalism can be found in the "Six W's" - Who?, What?, When?, Where?, Why? and, uh, hoW?.  We also learned that teacher couldn't spell that day.&lt;/p&gt; &lt;p&gt;I humbly submit that these same Six W's should be applied a bit more rigorously to software development and project management, just in case you're &lt;a href="http://www.codinghorror.com/blog/archives/000917.html"&gt;trying to figure out if your project will fail or succeed&lt;/a&gt; (and if you're not trying to figure out, it will fail).&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;The Important W's&lt;/span&gt;  &lt;/p&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;(in no particular order)&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;What (are we doing)?&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This one seems so obvious that it should require no explanation, but the flip side of that is that it's so essential that you're dead in the water if you and everyone else on your team can't explain what you're doing.  The team should know what you (collectively) are doing in the macro sense and they should have direction in the micro sense.&lt;/p&gt; &lt;p&gt;If you or any of your team can't accurately (and hopefully, clearly and concisely) verbalize just what you're doing, your project's probably well on its way to being &lt;a href="http://48klocs.blogspot.com/2007/06/maggot-therapy-for-code.html"&gt;necrotic&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;If you're a manager, you should be able to define achievable goals in the macro sense and the tasks needed to achieve them in the micro sense.  If you haven't and if your people can't either, see you at the unemployment office.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Why (are we doing it)?&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As a lazy software developer, I pose this question to the project management team a lot more than they'd like me to.  It's reflex and I think it does everyone a lot of good.  I don't want to try to wield phrases I won't understand in a million years like "cost-value proposition" but they're probably applicable here.&lt;/p&gt; &lt;p&gt;In hackneyed colloquialisms I can wrap my pea brain around, whose itch will your software scratch?  Will anyone take one look at it and immediately "get it"?  Will it make people spontaneously say "this is fucking cool"?  These are all really, really good things - if you know that people will think that it's fucking cool, you and your team probably does too, and will be excited and take pride in what they're doing, and the end product will reflect this.&lt;/p&gt; &lt;p&gt;Alternatively, will people take one look at what you've done and &lt;a href="http://www.knowing.net/PermaLink,guid,df0a45e4-0add-4598-9ac7-409774232094.aspx"&gt;shake their heads and gasp in disgust at the turd you've fished out of the shitter and slapped on the table&lt;/a&gt;?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Who (is doing it)?&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As in - do you have the people to accomplish your goal on hand already?  Or are you expecting that you'll just subcontract this out and everything will work out just fine?  Do you already have a team of studs or do you expect scrubs to "step up to the plate" and get things done?&lt;/p&gt; &lt;p&gt;If you don't have faith in your team's ability to accomplish it, listen to that nagging voice in your head and start running for the hills.&lt;/p&gt; &lt;p&gt;Projects can overcome a lack of manpower, but you probably don't have the stomach or the wallet to grunt your way through it.  With amorphous direction and unclear goals, even a team of ICFP-certified development gods are going to flounder.&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:180%;"&gt;The Unimportant W's&lt;/span&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;How are we doing this?&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This applies to those "little things" like IDE, language and framework.  I don't mean to underplay the importance of all of these; you'll certainly make your work more difficult (OK, orders of magnitude more difficult) if you choose something pretty inherently unsuited for the task (RoR for an embedded system, C for a web application), but I also think that one of the other W's easily steamrolls it - Who.  You put your team of studs up to the task and it stands a reasonable chance of succeeding in spite of itself.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Where am I doing this?&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This doesn't speak so much to physical location as to metaphysical location.  Oh, did I just blow your mind?&lt;/p&gt; &lt;p&gt;By that, I mean things like version control (where the project lives), and build management.  I'd lump bug tracking in here too.  &lt;a href="http://www.dehora.net/journal/2007/01/3_pillars.html"&gt;I know that Bill de hÓra would disagree&lt;/a&gt; and the developer in me wants to agree with him, but then I got to thinking - "hmm... VCS hasn't been around forever and I'm sure some working projects have teams that still pass around spreadsheets with a list of outstanding bugs on them."  More importantly, the &lt;strong&gt;Who&lt;/strong&gt; will overcome it - good people know good practices.  If we walk into an shop without version control, &lt;a href="http://48klocs.blogspot.com/2007/05/i-have-man-crush-on-subversion.html"&gt;we'll set it up&lt;/a&gt;.  It's not hard to find a bug tracker out on the internets, it's a couple days to roll your own and if all else fails, spreadsheets aren't the dumbest way to go about things (OK, they kind of are).  All this goes out the window once you meet a certain critical mass of project size, but the &lt;strong&gt;Who&lt;/strong&gt; will obviate it again, as you'll get good people in there that will make you hire build engineers and all that jazz.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strike&gt;When&lt;/strike&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Uh, now?  I've lived through multiple dot-bombs, so spare me the "the market just wasn't ready for our innovation" speeches.  See &lt;strong&gt;Why&lt;/strong&gt;, jackhole.&lt;/p&gt; &lt;p&gt;Boiling it down to Solomon's Law (YES!), "Code cannot overcome reality."  If the reality is that you've got an inept team, are lacking direction, are developing something that nobody wants, it doesn't make one goddamned bit of difference that you've got an A-number-one build system, magical bug tracking, distributed version control and an immaculate code base built on the right language and framework for the job.&lt;/p&gt; &lt;p&gt;No matter how beautiful the package, you're still boxing up a turd.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-2748676687145204731?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/2748676687145204731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=2748676687145204731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2748676687145204731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2748676687145204731'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/07/software-development-journalism-model.html' title='Software development - the journalism model'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4375532013564218356</id><published>2007-07-21T18:23:00.000-07:00</published><updated>2007-07-21T15:13:21.977-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='requirements documents'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Oral Traditions in Software Development</title><content type='html'>The requirements document will be the death of me.  I don't have a whole lot of faith in the requirements document if only for the fact that I've yet to work with one that concisely and accurately expresses the needs and intent of everyone that it represents.&lt;br /&gt;I can't stress this highly enough: I'm not very smart and I don't have much of an attention span.  That's why "concisely" matters so much to me.  You can make that requirements document accurate, but in the process you'll probably end up with &lt;a href="http://48klocs.blogspot.com/2007/05/case-for-mcmansion-architects-part-1.html"&gt;something resembling the Yellow Pages for Manhattan&lt;/a&gt;.  It's accurate up until the point where it puts me to sleep (about three paragraphs that resemble legalese in) and sooner or later, people will get hip to the fact that I didn't read it.&lt;br /&gt;OK, I'm taking that a bit too far.  I do read it as much as I think I need to in order to get the flavor of what I'm developing.  People sweat way too much over getting into the down and dirty of how things are supposed to work, pre-chewing the details.  For downstream consumers of this product (QA, client-facing folks and beyond) maybe this is a good thing?  For me, I just want the broad strokes and I'll be able to fill in most of the blanks.&lt;br /&gt;To fill in the gaps between the broad strokes, there's back and forth where I talk it out with the person who wrote the requirements document, because they know what we need better than I do.  This works out great for everyone as we quickly hash out details and get back to what we need to do.&lt;br /&gt;Well, it's great until months from now, when QA will have a new set of questions that weren't reflected in the original documentation because they didn't sit in the series of little meetings that development had with the requirements crew.  And we'll have another sit down and chat and they'll see what the real intent of the functionality is or I'll go back to the drawing board.&lt;br /&gt;Here's the thing - I really like how this works.  Little meetings (30 minutes or so) when needed and when the particulars can fit it into their schedule.  I don't have to read much of the documentation which is good for so many reasons, but mainly because people can tell me what they need better than they can write about how things should work.&lt;br /&gt;But here's the other thing - I can see how one would look at this and be calculating a &lt;a href="http://www.jaredrichardson.net/blog/2005/08/02/"&gt;bus number&lt;/a&gt; of "one."  The person that wrote the requirements document leaves the company and all of a sudden, you're back to just that dry document that's a subset of the expertise that they brought to the table.  The developer leaves the company and all the discussions that the product developer had with them that they never inserted back into the original document disappear with it.  People are left to scratch their heads over what's going on in with the application, not knowing that this is expected behavior.&lt;br /&gt;Or QA or someone else walks into the application with the expectations laid out by the requirements document and finds that the fantasy of the documents doesn't meet the reality of the application.&lt;br /&gt;I don't like documents.&lt;br /&gt;I like talking things out.&lt;br /&gt;I have no idea how to blend these two competing desires and turn what amounts to an oral tradition into a sustainable development model but if I figure it out, I figure I'll be a billionaire and then it'll be time to settle down to my life's ambition, hunting the most dangerous prey of all - MAN.  Just fucking with you, I'll be so rich I'll pay someone to hunt MAN for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4375532013564218356?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4375532013564218356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4375532013564218356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4375532013564218356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4375532013564218356'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/07/oral-traditions-in-software-development.html' title='Oral Traditions in Software Development'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1211011843603505251</id><published>2007-07-16T22:00:00.000-07:00</published><updated>2007-07-16T20:01:51.505-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coffee'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>THE MOST IMPORTANT BLOG POST OF THE YEAR</title><content type='html'>&lt;p&gt;As the internets tell me Paul Erdos famously told other people, "A mathematician is a device for turning coffee into theorems."  I can't find any way to fault that logic.  The man does, after all, know from logic and as far as logic goes, that shit is &lt;em&gt;airtight&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;My personal spin on this is that "A developer is a device for turning coffee into arable software."  This, likewise, is &lt;strong&gt;airtight reasoning&lt;/strong&gt; and to claim otherwise is to beg for your License To Internets to be revoked.&lt;/p&gt; &lt;p&gt;Inexplicably in the wilds of N'Hampsha, it gets hot up here.  Sometimes ugly hot - about a month back it was 95 degrees and the relative humidity was at like 180% or something (before you furiously type and complain, remember that Erdos is the super-stud mathematician and I'm the forgettable developer).  9 months of winter and then we get this?  So funny I forgot to laugh.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Days like these, I don't want home-brewed hot coffee, I want iced coffee.  But who wants to buy iced coffee out at the coffee spots?  With very few exceptions, I read "iced coffee" as "the shit that we brewed hours ago and didn't sell and it's too stale and bitter to sell hot but with a few ice cubes in it the rubes will drink it up."  Lemons from lemonade and all that.  But seriously - most iced coffee is bitter and stale.  I've made my own at home by brewing hot coffee extra strong so when I poured it over lots of ice, it'd even itself out.  Which works out OK, but I don't really want to turn on the electric kettle and boil water when it's that damned hot out.  I just want some tasty iced coffee.&lt;/p&gt; &lt;p&gt;Inexplicably (oh, dissssss), it's the NY Times to the rescue with &lt;a href="http://www.nytimes.com/2007/06/27/dining/27coff.html?ex=1340683200&amp;amp;en=0a9cf1fb9bdd34ea&amp;ei=5124&amp;amp;partner=permalink&amp;exprod=permalink"&gt;a recipe for cold-brewed iced coffee&lt;/a&gt;.  But I've rambled on long enough and you don't need to read their snooty rambling in addendum to mine (you can if you want) and I don't know why they tell you to dilute the mixture.&lt;/p&gt; &lt;p&gt;For starters, the hardware - they have some retarded elaborate mason jar + cheesecloth + sifter combination, but &lt;span style="font-style: italic;"&gt;fuck that noise&lt;/span&gt;.  I normally make my coffee in a french press and I figure coffee's not going to get stale sitting out at room temperature (I'll experiment in the name of science on this soon enough, but my past experiments have shown the french press to work quite favorably), so if you don't already have one, maybe it's time to get one.  Twenty bucks.  Totally worth it.  Makes hot and now cold coffee.  Win.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;So you grind the coffee (the normal amount that you'd brew with) as always.&lt;/p&gt;&lt;p&gt;And then you pour some cold water in (the amount that you'd normally brew the grinds with) and stir it up and, uh.  That's sort of it for the steeping step.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; THEN... it sits overnight.  And in the morning, you push the press down and pour over ice and you win.  As advertised, it's not bitter at all (you don't buy shitty roasts, right?) and adding a bit of &lt;a href="http://www.nhmilk.com/"&gt;heavy cream&lt;/a&gt; makes it almost candy-sweet.  A little if you want but it's pretty damned fine all by itself over ice.&lt;/p&gt;&lt;p&gt;You've read this post, now you can safely turn off the internets because I can't imagine ANYTHING BETTER COMING FROM ANYWHERE ON THE ECHO CHAMBER OF THE INTERTUBES ANYTIME FOR THE REMAINDER OF THE YEAR.&lt;/p&gt;&lt;p&gt;Unless I decide to post again in which case all bets are off.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1211011843603505251?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1211011843603505251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1211011843603505251' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1211011843603505251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1211011843603505251'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/07/most-important-blog-post-of-year.html' title='THE MOST IMPORTANT BLOG POST OF THE YEAR'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1580337635293461489</id><published>2007-07-10T20:58:00.000-07:00</published><updated>2007-07-10T18:07:12.121-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='requirements documents'/><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><title type='text'>Agile Development - Can We Stop Designing?</title><content type='html'>Over on some programming forums I frequent, someone posed the following question that resulted in some heated development (from Agilists and others).&lt;br /&gt;"We have a team that tells us that because they have adopted 'agile development' they no longer need to do any design work before writing code.&lt;br /&gt;&lt;br /&gt;To me this seems bizarre, I can't fathom how one could build any reasonably complex application without a modicum of design (hell, even pencil sketches of UIs or something), but they claim it works.&lt;br /&gt;&lt;br /&gt;Is it reasonable to develop complex applications with zero design work?"&lt;br /&gt;&lt;br /&gt;BUFD (Big Up-Front Design) has gotten a hell of a black eye, but damned if I can think of a better way to wrap my head around a project in a business domain that I'm completely unfamiliar with.&lt;br /&gt;Generating documents is a mixed bag - I think they're great for the process you use to create them (collaborating with everyone involved in the project, picking brains, exposing flaws and needs and hopefully constraints early) but I think they're awful for the fact that the end product is a document that's outdated a week into the development process (give or take; the point where the bulk of your time is developing rather than documenting) and at that point, the different partners have vastly different ideas about what the document means.&lt;br /&gt;Developers think it's a rough roadmap (do I update the documentation with the way things will work in our system?  I'll get that later... OK, not really.  Have a meeting?  That gets old REAL fast), most everyone else (project managers/QA/stakeholders) think it's litany and that's a sure-fire recipe for friction.&lt;br /&gt;Eschewing the design portion of this and flying by the seat of your pants elevates this from an exercise in friction between developers and, well, everyone else to an exercise in sure-fire catastrophe for everything but the most trivial of implementations.&lt;br /&gt;This isn't to say that reasonably complex applications can't be done without BUFD - I'm sure that they can, but with a big fat caveat: the developers have had a reasonable amount of experience with the business/application domain that they're developing for.  There you can come away with a working application in the void of BUFD but with yet another gotcha: no one has any solid expectations of what to expect when the developers pull away the veil.&lt;br /&gt;If you're working in an "agile" fashion, I guess this means that you're going to have rapid iterations from developer to project managers/stakeholders at which point they'll yea or nay it and talk about what else needs to be done, which probably means throwing away a fair bit of what you're doing, which means that instead of doing BUFD, you're doing Smaller Bits And Pieces Of Design All Allong (SBAPODAA).  On the upside, there's that boost of "look what we're getting done".  On the downside, there's that "holy crap I had to throw out another fucking day's work because Joe Blow From Product Management couldn't have told me yesterday that's not how things work?" and on the real big downside, there's the very real possibility that you're going to scuttle the project wholesale because developers are arrogant and think they know how to do everything so much better that you end up with a brilliant application that just happens to be absolutely useless for what the stakeholders need it to do.&lt;br /&gt;I'm pretty sure that pair programming doesn't solve that one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1580337635293461489?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1580337635293461489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1580337635293461489' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1580337635293461489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1580337635293461489'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/07/agile-development-can-we-stop-designing.html' title='Agile Development - Can We Stop Designing?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-1321487639581918416</id><published>2007-06-29T19:45:00.000-07:00</published><updated>2007-06-30T07:09:08.446-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Maggot therapy for code</title><content type='html'>Showing the project owner what I'd done, she had one big question for me.  "You started from scratch?"  Accompanied, of course, by an incredulous look.  So much for subtext.&lt;br /&gt;But let's back up for a second.&lt;br /&gt;So I spent a few months last year building a bunch of pieces of functionality to support a new business need.  Late (but under-budget! (since I was the only person working full-time on it)) and hairy as anything, but it more or less works at least some of the time.  Hairy enough that when asked "can it do this?" most of the time I roll my eyes and groan and tell them "it's complex and fragile and I'm not sure so I'd guess it'll take me a week" and then sometimes I've already built the functionality.  I laugh at Peoplesoft for being Rorschach software and look - I've built some of my own.&lt;br /&gt;As time's gone on, I've gone back in and refactored bits and pieces and have new objects that branch out of the old (that are probably better, honest!).  I inherited one subset of these associated objects from a recently-departed coworker.&lt;br /&gt;I've made enough bugs of my own in the past that I worry about other people interacting directly with my stuffs and making me look like a jackass that I've done code audits of the work, so I knew what I was in for.&lt;br /&gt;Loop unrolling.&lt;br /&gt;Bona fide magic numbers.  "OK, so there's codes of 3, 4 and 7 that I can apparently pass down from the presentation tier.  These are enumerated in the business tier, right?  Guess not.  Data tier?  No.  Oh - they drive branching in the stored procedure.  Brilliant."&lt;br /&gt;Leaky abstractions.  As in the presentation tier sometimes calling business objects, others the data tier, still others the database.  Plus handling business logic in the presentation tier.&lt;br /&gt;Code paths in the business tier and database that weren't called in the database - so stored procedures and methods that were essentially dead code.&lt;br /&gt;I'd already given the work a vote of no confidence, so when it was handed to me, I went with my gut - tactical nuke.&lt;br /&gt;But there was that nagging voice in the back of my head.  "Good job, Dave - way to go with Not Invented Here Syndrome.  Worse, you're exhibiting It Has Been Invented Here, But I'm Too Lazy To Read The Fucking Code So I'll Just Do It All Over Again Syndrome."  Couldn't I have spent this week doing something more productive, just fixing the bugs that were logged and moving on, rather than re-doing it pretty much from scratch, virtually guaranteeing that I've introduced more in its stead?&lt;br /&gt;I guess there's that, but given all the code smells... and honestly.  Loop unrolling?  I've only seen shit like that on &lt;a href="http://www.thedailywtf.com/"&gt;The Daily WTF&lt;/a&gt;.  Who does that shit?  Magic numbers?  Yow.  I've sort of taken an ambivalent stance on them in the past, but when "magic number" means "you have to open up the stored procedure to figure out why the presentation logic passes down this value in this circumstance", I have to scratch my head.&lt;br /&gt;I referred to it as applying a "tactical nuke" when I checked it in, and that too gave me pause.  I mean, &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html"&gt;Joel says you should never completely rewrite it&lt;/a&gt;, so you should never completely rewrite it, right?&lt;br /&gt;In medicine (and thank god I don't know this from personal experience), sometimes wounds become necrotic - the tissue's been so damaged that it's no longer living.  At times like these, doctors have to become a bit, shall we say, "inventive."  I can't think of any other way to describe applying maggots to a human being for medicinal purposes.  From the Wikipedia article on maggot therapy (which I'm not linking because &lt;span style="font-style: italic;"&gt;fucking eww&lt;/span&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;The maggots have three principal actions reported in the medical literature:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;debride wounds by dissolving only necrotic, infected tissue;&lt;/li&gt;&lt;li&gt;disinfect the wound by killing bacteria; and&lt;/li&gt;&lt;li&gt;stimulate wound healing.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;So calling it a "tactical nuke" was going way overboard.  There were bits and pieces in there that worked pretty well.  Not the way I would have done them, but I won't argue with working code that works in a reasonably intuitive fashion.  So I left the living pieces and excised the suspect ones, the untenable ones.&lt;br /&gt;Two days later, I ultimately think I did the right thing.  Two weeks later, after QA's gotten to bang on it, we'll see how confident I am in my skills as Senior Systems Maggot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-1321487639581918416?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/1321487639581918416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=1321487639581918416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1321487639581918416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/1321487639581918416'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/maggot-therapy-for-code.html' title='Maggot therapy for code'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5413871447888836830</id><published>2007-06-23T13:12:00.000-07:00</published><updated>2007-06-23T13:43:37.419-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management software'/><title type='text'>Management smells: don't ask</title><content type='html'>Let's suppose you're not a programmer.  Then let's further suppose you've never known a programmer... yet you manage them.  Where do you go to figure out what makes them tick and how to work (OK, deal) with them?&lt;br /&gt;Imagine that all you knew about programmers you learned from &lt;a href="http://www.joelonsoftware.com/"&gt;Joel on Software&lt;/a&gt; and the &lt;a href="http://en.wikipedia.org/wiki/Jargon_File"&gt;Jargon File&lt;/a&gt;.  OK, the latter's really a stretch because &lt;a href="http://www.cultdeadcow.com/cms/textfile_index.php3"&gt;t-files&lt;/a&gt; are, like, so old.  Between reading the two, one would get the impression that programmers are some sort of super-genius prima-donnas dropped in from another dimension with its own bizarro set of social mores.&lt;br /&gt;But in-between the auto-hagiography, you'd find them staring gleefully at some gems, like this tidbit taken from the Jargon File's &lt;a href="http://www.catb.org/%7Eesr/jargon/html/S/SNAFU-principle.html"&gt;entry on the SNAFU principle&lt;/a&gt;.&lt;br /&gt;&lt;a id="SNAFU-principle"&gt;&lt;span class="quote"&gt;&lt;blockquote&gt;True communication is possible only between    equals, because inferiors are more consistently rewarded for telling their    superiors pleasant lies than for telling the truth.&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/a&gt; So have you figured out my clinically-developed, painstakingly-researched advice for you?  Talk to your people.  It shouldn't be that difficult to figure out.  As a manager, do you work with people or do you just crack the whip and shit magically appears?  I'm guessing you work with people.&lt;br /&gt;No matter how smart or alien they may seem to be (and when you ask them how it's going, you may get an answer in what approaches moon-man), people all generally share the same sort of motivations.  Food in the belly, roof over the head, meaningful work.&lt;br /&gt;The meaningful work thing can be a hard sell - at the end of the day, how many people do you know that get PUMPED up for Industry X?  You can sell tickets to a rock show, but you have to bribe people into attending that process improvement meeting with the lure of free lunch (and bottomless cups of coffee).  But you can become the meaning for them.  Ask them how things are going.  If there are any problems that they've encountered.  What successes they have.  Show interest in what they have to show you, even if it's not much.&lt;br /&gt;If you can't find the time in your busy day to show any interest in what they're doing, don't be surprised when they show a concomitant level of care and interest in the product they're creating for you.  Huh.  Maybe those semantically-challenged scrum maniacs really are &lt;a href="http://www.controlchaos.com/old-site/implem.htm"&gt;on to something with those daily meetings&lt;/a&gt; after all?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5413871447888836830?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5413871447888836830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5413871447888836830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5413871447888836830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5413871447888836830'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/management-smells-dont-ask.html' title='Management smells: don&apos;t ask'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-542150961577928688</id><published>2007-06-19T20:28:00.000-07:00</published><updated>2007-06-19T17:28:17.522-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='unintentional irony'/><title type='text'>Seeing the code rather than the product</title><content type='html'>Unintentional irony is never a pretty thing.&lt;br /&gt;A feller out on that there interweb started off so strong - &lt;a href="http://typicalprogrammer.com/programming/learning-by-example-javacript-luhn/"&gt;people who write books or knowingly put code out in the public domain for learning purposes should hold themselves to a higher standard&lt;/a&gt;.  Amen to that, brother!  And the comments invariably start filling up with other folks linking from reddit.com who just &lt;span style="font-style: italic;"&gt;have&lt;/span&gt; to whip 'em out and show the guy that &lt;span style="font-weight: bold;"&gt;they know micro-optimization like nobody's business&lt;/span&gt; and never mind missing the writer's point (make your code correct and readable, especially if people who might not know any better are going to be learning from it).&lt;br /&gt;And then I took a look at what exactly the writer was railing against - an example from an AJAX book about how to validate credit card numbers in Javascript.&lt;br /&gt;If you could take a moment from furiously hacking away at that ZX-80 assembler solution to the problem, let's jump to the point so you can get back to it.&lt;br /&gt;The book's suggesting something completely fucking insane - client-side validation of credit card numbers - and the most offensive thing about that is that the code's cribbed poorly from a Wikipedia entry?&lt;br /&gt;Back in high school, one of my computer science professors graded starter programs by the "cat on the keyboard" test - subject to random input, will your program gracefully handle it or will it shit the bed?&lt;br /&gt;Rule number one-or-so of client-server development (and sorry, Web 2.0-aholics; it's still client-server no matter how semantic or semiotic or other big words I don't understand-ic you try to make your app sound) is: never trust client input.  Their cat could be walking on the keyboard or, when there's money on the line, they could be trying to game the system.  &lt;span style="font-weight: bold;"&gt;Validation of any critical data has &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;absolutely no place being performed on the client-side&lt;/span&gt;.  My two cent AJAXy solution?  Make a web service you can call to handle the &lt;span style="font-weight: bold;"&gt;server-side&lt;/span&gt; validation and then make your AJAXy call to that service when appropriate to see if the credit card number's valid to give the user the immediate UI response you crave.&lt;br /&gt;Don't get so wrapped up in your code that you lose sight of the product and basic common sense.  When the music stops, you don't want to be the guy &lt;a href="http://weblogs.asp.net/alex_papadimoulis/archive/2005/05/25/408925.aspx"&gt;earnestly deliberating about whether to pound that nail with a shoe or glass bottle&lt;/a&gt;.&lt;br /&gt;I still haven't gotten the scuff marks and shards out of my wall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-542150961577928688?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/542150961577928688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=542150961577928688' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/542150961577928688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/542150961577928688'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/seeing-code-rather-than-product.html' title='Seeing the code rather than the product'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4880966662750564687</id><published>2007-06-18T21:50:00.000-07:00</published><updated>2007-06-18T19:12:51.725-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>A love letter to the software QA folks of the world</title><content type='html'>In our twisted little minds, we're fashioning castles out of dirt, breathing life into the imaginary peasants that inhabit the castle and coming up with new and fascinating ways to teach the little people to exercise functionality.   Nothing could be wrong with my castle!   I built it myself from scratch!  Can't you see all the little people in there grinding away just like I taught them to?&lt;br /&gt;But oh!  There be a storm brewing!  Eventually we have to put down our magic wands and show people just what we've been up to and there's the QA folks.  Looking everything over with a discerning, non-paternal, eye and pointing out that I'm just an idiot playing with dirt and by the way that castle you built?  The walls aren't up to spec.&lt;br /&gt;Developers and QA operate in an antagonistic relationship.  We build things that we're proud of (and if you're not proud of what you're building, you're making their job a hell of a lot easier) and they knock it down.  Maybe it's because I'm an entirely reliable source of bugs, but on the whole, it's been mostly mock antagonism.  True, I enjoy tagging bugs as "unable to reproduce" or "user error" more than I should, but at the end of the day, I appreciate that there's someone checking what I'm producing and verifying that it's not all wrong.&lt;br /&gt;I'd tell you that I test as much as I can, but if I told you that, then I'd be pretty hard-pressed to explain some of the head-scratchers I've released in the past.  Can I blame it on not using test-driven design?  Not being agile enough?&lt;br /&gt;Developers get the cool software toys.  I've seen a few QA test environments in action and they're pretty execrable, little better than the (super-awesome and totally deserving of the coveted Dave Solomon Seal of Approval) &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt;.  I can get &lt;a href="http://48klocs.blogspot.com/2007/05/i-have-man-crush-on-subversion.html"&gt;unnaturally pumped about source control&lt;/a&gt;.  What else is there to get psyched about in the world of QA software?&lt;br /&gt;We get the cool development methodologies.  Test-driven design (jesus christ we're developers pretending to be QA!  are we trying to put you folks out of a home?).  Agile.  Scrum.  What do QA folks get?  Seriously.  I have no idea.&lt;br /&gt;Worst of all, the project timelines.  When the specs take too long to get hammered out and development drags on too long because the software's more complex than expected (leaving more nooks and crannies for bugs to fester in), what does your enterprising project manager propose as the solution?  Push the release date back?  Nah.  Just cut the QA cycles short.  Sell the sizzle, the quality of the steak be damned.&lt;br /&gt;How many projects will be haunted to their grave by that decision?&lt;br /&gt;So here's to the software QA testers of the world.  Despite being forgotten children when it comes to software, viewed as a liability by managers and loathed by developers afraid to eat their own dog food, you somehow manage to persevere and keep the quality up.&lt;br /&gt;Just quit going over my code with a fine-tooth'd comb, willya?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4880966662750564687?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4880966662750564687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4880966662750564687' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4880966662750564687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4880966662750564687'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/love-letter-to-software-qa-folks-of.html' title='A love letter to the software QA folks of the world'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6116760575896322521</id><published>2007-06-12T23:21:00.000-07:00</published><updated>2007-06-12T20:22:28.981-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Object-oriented management - throw new DevelopmentException();</title><content type='html'>&lt;p&gt;From what little I can remember of object-oriented design from school, there was next to no attention paid to something that, in my idle thinking, makes OO implementation a whole lot more pleasant - exceptions. There's an analogy to development management in mind here, but to draw it fully I think that I need to lay out how and why I use exceptions in my object design first.&lt;/p&gt; &lt;p&gt;So let's say that you're developing an object. It performs functions that may or may not succeed - how do you communicate failure? At a simple level, there's good old booleans. True/false - the method call succeeded or it didn't.&lt;/p&gt;&lt;pre&gt;class Foo {&lt;br /&gt; public int Bar;&lt;br /&gt;&lt;br /&gt; public bool Retrieve(out MissingRequiredValueBar) {&lt;br /&gt;   MissingRequiredValueBar = (this.Bar == 0);&lt;br /&gt;&lt;br /&gt;   bool returnValue = false;&lt;br /&gt;&lt;br /&gt;   // retrieve stuff!&lt;br /&gt;&lt;br /&gt;   return returnValue;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public bool Save() {&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So this does a reasonable job of telling the whole story... in a simple case. But look at that Retrieve method - we've got two booleans to juggle already - pass/fail, plus an error state that we need to return explaining why things fail.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;How do we know that the calling method's checking and working with both of those booleans?  Boy, it'd sure be bad if they didn't.  And what about Save?  They know that returning false means that the data wasn't saved, right?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Furthermore, in a more complex case, I don't think it's hard to see (I'd show you some old code I'm ashamed to have written if I could) that our Retrieve() method's going to metastasize into a hideous mass of parameters. The more parameters you have, the better the odds that you won't have or need one in a calling scenario; &lt;a href="http://en.wikipedia.org/wiki/Method_overloading"&gt;method overloading&lt;/a&gt; can only take you so far. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Maybe you're thinking of another way out of this jam. Divorce the return parameter from the method call and make it another public property, right? So very wrong.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Do that and you're depending on the person calling your class to have intimate knowledge of how things work ("Oh - first I call Retrieve(), then if it fails I check this other property to see why it failed."). That's a best-case scenario and even there, you're not impressing anyone. In a worst-case scenario, your class has been transformed into an API and the developer on the other end is reaching for a &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;decompiler&lt;/a&gt; while promising to punch whatever idiot was responsible in the throat for this godawful code that's been foisted upon them. Not that I've ever made that promise.  Objects love &lt;a href="http://en.wikipedia.org/wiki/Loose_coupling"&gt;loose coupling&lt;/a&gt;, remember?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So let's take another stab at this awful example of a class but use exceptions this time.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;class Foo {&lt;br /&gt; public int Bar;&lt;br /&gt;&lt;br /&gt; public bool Retrieve() {&lt;br /&gt;   if(this.Bar == 0) {&lt;br /&gt;     throw new MissingRequiredDataException("You need to supply a non-zero value for Bar in order to call Retrieve.");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   bool returnValue = false;&lt;br /&gt;&lt;br /&gt;   // do stuff!&lt;br /&gt;&lt;br /&gt;   return returnValue;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public bool Save()  {&lt;br /&gt;   throw new FunctionalityNotImplementedException("Save functionality isn't working yet.");&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;A common critique of exceptions (along with the baffling observation that "throwing them is slow") is that they shouldn't be used as flow control.  And you know what?  I absolutely agree.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;But notice - exceptions aren't being used as flow control, they're being used as &lt;em&gt;cessation&lt;/em&gt; control. The exception message is unambiguous as to how to resolve the problem.  Whether it's being used as an API or simply as a black-box object by a co-worker, it's clear what needs to be changed in the calling class to avoid the exception.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I used to write classes and have little &lt;strong&gt;todo&lt;/strong&gt; comments littered all over the place.  It wouldn't be long before I'd get things bootstrapped far enough along to start testing.  Something goes wrong upstream and I spend time debugging to eventually realize/remember that I hadn't implemented that piece of functionality that I was trying to use yet. With exceptions, there's no ambiguity as to the source of the problem.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;See how Foo's Save method blows up obviously?  Would you prefer spending time figuring out why Foo's data isn't showing up in the database?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you're not already converted, I imagine that it sounds like we'll be awash in a sea of exceptions, right? While your objects are in development and people are discovering the rough edges, yeah.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;But as time goes on, a curious thing starts to happen - you and your co-workers get tired of getting bombarded with exceptions and you start to &lt;em&gt;fix them&lt;/em&gt;.  Yesterday's exception becomes today's new use case or available error state.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Summing up exceptions, I like them because...&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Your class knows best when something's gone wrong and should have the ability to call a complete stop to the proceedings&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You have the ability to provide context to the object's consumer that they obviously need&lt;br /&gt;&lt;/li&gt;&lt;li&gt;They make it very clear what isn't working with your class as you exercise it&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The calling class can treat your object as a black box - all it knows is that either their call worked or it blew up and why&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The calling class has the option to let that exception bubble up to its subsuming classes or to nip it in the bud right there&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Error states can be misdiagnosed or ignored, exceptions will stick around until the process responsible is fixed&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;So here's where I make the big leap from merely being a so-so developer to being a clueless, completely inexperienced, hopelessly naive manager-wannabe, but I don't think this is the stupidest assertion I've ever made.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Problems employees face should be treated like exceptions and bubbled up to their manager as soon as possible.&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As a manager, you trust that your employees are doing their work, but for the most part, you want to leave them be and have trust that what they're doing is working.  In that sense, you're treating them like objects - do you step through every line of code of every class that you call or do you validate the inputs and outputs and take it as a matter of faith that things are working as expected since it looks OK?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;When it comes to developers, there seem to be three ways to handle problems that crop up.&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;"What problem?  Don't worry about development going long, we'll just make up for it by cutting the QA cycle a little short.  It's not a big deal, because if a component took longer to implement than expected because of the complexity, you can be sure that there won't be too many problems in the finished product that I'm hurrying to make."&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"Holy shit I had to open up a debugger today because Dave's Foo class threw an exception when I tried to Save &lt;strong&gt;we are going down in a sinking ship&lt;/strong&gt;."&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"I know that I promised you that Foo in two months' time and I've only been on it for a couple of weeks, but I didn't realize how crufty the surrounding portions are.  If I have the time to refactor classes ancillary to the new functionality, it'll take longer but should ultimately be more stable.  If not, I can shoehorn it in but it likely isn't going to be pretty or stable."&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;#1 is probably the most common way.  People don't like to throw exceptions because at its heart, you're admitting failure when you do.  They don't like to cop to being late or not having features complete because again, admitting failure.  At best you'll pull teeth and get some status information to work with.  But how do you know how severe the problem is or isn't?  How can you trust the status they're giving you?  At worst, they'll be completely silent about how things are going until the day before the gold build at which point maybe they'll dig deep into their bag of tricks and pull the 24 Hour Push Of Redemption out.  It's too late for you to let anyone up the ladder know at this point.  Pull teeth earlier next time.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;#2 is the sky is falling way - dealing with them, you know that you're going to be awash in a sea of noise.  If you listen to the roar, you'll be convinced that the sky is falling too.  Then the sun will rise the next morning and over time you'll learn to take what they say with a big grain of salt - you'll implement processes to deal with this constant stream of exceptions.  It's perfectly permissible to catch exceptions if you know what you're doing, but when you know what you're doing, you know that there are times when you have to let them bubble up or add context and re-throw them.  A doctor's going to be annoyed dealing with a hypochondriac, but even a hypochondriac genuinely gets sick sometimes.  Still preferable to being blind-sided by an error state.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;#3 is about the best you can hope for (and what I hope my way is) -they don't overreact to problems but at the same time, they don't try to sugarcoat any of the big, project-threatening, hurdles in the way.  Figure out what the blockades are in the process and try to resolve them.  &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Over time, you'll see trending - what exceptions are my employees raising to me most?  Chicken Little's saying that the machines aren't beefy enough to keep up?  You can probably back-burner it for a while.  The Late-Warning, Silent Type's griping about the compile speed of the machines?  Time to freshen up that hardware.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You'll react to the exceptions as you need to and (hopefully) resolve them as you see that you need to and can.  You'll implement processes to catch the ones you can, to quash the ones that don't matter and to bubble up the ones that are nightmares.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Then again, I'm a developer who thinks of co-workers as objects and problems that a project faces in terms of exceptions.  Worst.  Metaphor.  Ever?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6116760575896322521?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6116760575896322521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6116760575896322521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6116760575896322521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6116760575896322521'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/object-oriented-management-throw-new.html' title='Object-oriented management - throw new DevelopmentException();'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6010349020148477143</id><published>2007-06-07T21:00:00.000-07:00</published><updated>2007-06-08T06:57:35.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>WTF exactly is wrong with The Daily WTF's site rename?</title><content type='html'>&lt;p&gt;Ladies and gentlemen, a new pithy tenet of the software development world has been born into life.&lt;/p&gt;&lt;p&gt;Before, we had to slum it with lame old one-or-two-liners like...&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;The first 90% of development will take 90% of the time.  The last 10% of development will take the other 90%.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;Perl is write-only.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;Java is the new COBOL.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;But that's so pre-web!  We need to get with the times and have something that goes down easy in our RSS readers!  So we have a new one!&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;The Daily WTF sucks now that the WTF stands for "&lt;a href="http://worsethanfailure.com/Default.aspx"&gt;Worse Than Failure&lt;/a&gt;."&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;Has the quality of the postings gone down?  I don't think so.  With new editors there and the 3 posts/day that they're churning out, there's bound to be some that don't quite fire on all cylinders, but I get a chuckle or a sad shake of my head out of something most every day there (still).  That said, I can't lie and tell you that I'm some sort of sophisticated gentleman.  I play video games and laugh at fart jokes so I obviously don't know from quality, plus I might have &lt;a href="http://www.cpsc.gov/cpscpub/prerel/prhtml86/86070.html"&gt;licked my old Voltron toys to get them to stick together better&lt;/a&gt; when I was a kid so I might be a little (OK, a lot) retarded.&lt;/p&gt; &lt;p&gt;Is there really that much in a name or is there more to it?  Obviously, I think there's more to it, and here goes.&lt;/p&gt; &lt;p&gt;When it was The Daily WTF and the WTF stood (spoiler alert!) for What The Fuck, it was nothing more than a freak show.  Only in the place of the bearded lady and the world's largest horse, we had the programmer who overloaded booleans so he could enumerate FILE_NOT_FOUND!  Ha ha ha!  They're so much dumber than I am!  Can someone around here give me a big high five because I solved &lt;a href="http://48klocs.blogspot.com/2007/06/rethinking-fizzbuzz-function-z.html"&gt;FizzBuzz&lt;/a&gt; in Erlang the other day?  Paula Bean LOL!&lt;br /&gt;Now that it's Worse Than Failure, could it be that it cuts to the quick of that nagging fear that I've got in the back of my head.  Maybe it's in yours too... it says things like "I thought this object model was the bee's knees, but have I gone too far?  Can anyone but me support it?  Could I have done it a better, simpler way?"  Things like "What exactly is the point of all this?  There's a metric shit-ton of code and tables, but at the end of the day, does anyone appreciate what I've done?"  Things like "Is this what I have to show for the last few years of my life on this?"&lt;/p&gt; &lt;p&gt;Or, to paraphrase Morse, "What hath we wrought?"&lt;br /&gt;It hurts to think critically and realize that the system that you've worked so hard on probably should never have been built in the first place.  That those pet classes of yours might look like the Sistine Chapel to you, but to the rest of us they're little more than a house-shaped booby trap constructed out of snot, zip ties and duct tape, waiting to trap and maim us in new and unexpected ways each time we brush up against the walls.&lt;/p&gt; &lt;p&gt;That you've taken a rusty, but perfectly servicable, old DOS application and re-implemented it as a spanking new web app with all the fixins (AJAX!  MVC and so many other patterns!  Multi-threaded!).  You see a success, your users see that you've architected a monumental clusterfuck that's so ornery and unusable that they're keeping around their 386s because you've all you've succeeded in is failing their needs miserably.&lt;/p&gt;&lt;p&gt;That a lot of the time, development feels an awful lot like the Red Queen's Race.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Or maybe I'm missing the point altogether and have no clue &lt;a href="http://www.thedailywtf.com/"&gt;what the fuck&lt;/a&gt; I'm on about.  Has the quality really dropped, are &lt;a href="http://weblogs.asp.net/alex_papadimoulis/"&gt;Alex Papadimoulis&lt;/a&gt; and his associates sellouts (however that would apply) or should Shakespeare have wondered "what's in an acronym?"&lt;/p&gt;&lt;p&gt;Really, is the world a better, happier place because of what you've done?  Are people getting more out of your system than they're putting into it?  If your system disappeared tonight, would anyone care tomorrow or the day after that?  Is it possible that your successes are such untenable messes that they really are worse than failure?&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6010349020148477143?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6010349020148477143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6010349020148477143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6010349020148477143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6010349020148477143'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/wtf-exactly-is-wrong-with-daily-wtf.html' title='WTF exactly is wrong with The Daily WTF&amp;#39;s site rename?'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4495444383356836372</id><published>2007-06-04T21:01:00.000-07:00</published><updated>2007-06-04T18:03:24.111-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interviews'/><category scheme='http://www.blogger.com/atom/ns#' term='code smell'/><category scheme='http://www.blogger.com/atom/ns#' term='narcissism of minor differences'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='literacy'/><title type='text'>Code Smells - Developer Literacy</title><content type='html'>&lt;p&gt;Continuing &lt;a href="http://48klocs.blogspot.com/2007/06/rethinking-fizzbuzz-function-z.html"&gt;on the subject of interviews&lt;/a&gt;, if I could give one piece of advice to people job-hunting, it's this - proofread your resume.  It isn't hard, honest.  If I could give another piece of advice to developers actively writing code, it's this - proofread it.&lt;/p&gt; &lt;p&gt;When hiring time comes around, I have no trouble whittling down the candidate pool.  A middle-of-the-road candidate is getting tossed if their resume has misspellings or glaring grammar errors.  My grammar's awful enough that I wouldn't know a dangling participle if it hit me in the face (I know that they're bad, do I win a cookie?) but I do know to avoid tense shifts and other obvious biffs.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;But developers write in code, not in English!  Surely this is a case of &lt;a href="http://realfake.org/blog/2004/11/22/the-narcissism-of-minor-differences/"&gt;the narcissism of minor differences&lt;/a&gt;!&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I think it goes beyond that.  Misspellings are a code smell for me - if a developer can't be bothered to learn and properly apply the language that they've been speaking for 30 or 40 years, how much faith do I have in their ability to learn and properly apply a language that they've only been "speaking" for 5 or 10 years?  So, if I may retort...&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;If you don't proofread your resume/e-mail, how much faith should I have that you proofread your code?&lt;/p&gt; &lt;p&gt;If you don't proofread your code, how confident do you expect me to be in the fact that you've debugged it?&lt;/p&gt; &lt;p&gt;If you can't be bothered to crack open a dictionary, chances are you won't bother cracking open Google when you encounter a problem.  I imagine that you'll instead choose  to boldly and blindly rush head-first go into the same tar pit that so many arrogant developers before you have.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I won't go so far as to say that &lt;a href="http://www.hanselman.com/blog/DoesSpellingMatterIThinkItDoes.aspx"&gt;you should go out and get an editor&lt;/a&gt; (but the man is on to something), but I will say that you're not showing a whole lot of regard for the person on the other end if you can't spell right.  If the person on the other end is me then you're not instilling a whole lot of confidence in the quality and professionalism of your work either.&lt;/p&gt; &lt;p&gt;If the person on the other end of your typo'd code is you (and it probably will be) then why don't you love yourself enough?  You need a hug.&lt;/p&gt; &lt;p&gt;If I wrote the typo or awkward grammar, Word was broken and my internet's tubes were completely full of kittens that day so you have to forgive me (and not point it out).  After all, I'm just a developer.  You must understand - we write in code, not English.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4495444383356836372?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4495444383356836372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4495444383356836372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4495444383356836372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4495444383356836372'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/code-smells-developer-literacy.html' title='Code Smells - Developer Literacy'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-6758854693168495356</id><published>2007-06-04T19:19:00.000-07:00</published><updated>2007-06-07T15:45:39.843-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interviews'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Rethinking FizzBuzz - Function Z</title><content type='html'>The notion that &lt;a href="http://tickletux.wordpress.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/"&gt;a program as simple as FizzBuzz&lt;/a&gt; was over the heads of a non-trivial number of developer candidates caused a stir for the sort that reads programmer blogs.&lt;br /&gt;I was as astounded as everyone else was - here's a program that's a tiny step above HELLO WORLD in terms of its complexity and one can actually use it to weed people who call themselves developers (and have the experience on their resumes to back it up) out?  Really?  But at the same time, guy's got a point - why &lt;span style="font-style: italic;"&gt;don't&lt;/span&gt; we have prospective developers prove that they &lt;span style="font-weight: bold;"&gt;can&lt;/span&gt; really write code?&lt;br /&gt;In the mad dash to whip it out and measure their programming prowess, people missed out on pondering another fundamental need from candidates - reading code.&lt;br /&gt;Nobody wants to cop to being a lowly maintenance programmer.  The digs aren't hard to find - "cut and paste programmer", "they just cobbled the code together", "Java is the new COBOL", etc.&lt;br /&gt;But when you get down to it, how much of your code is really "new"?  Do you refactor relentlessly (or ever)?  Have you ever found a bug in your own code and fixed it?  Have requirements changed, leaving you to modify your classes to get things working as they should today?&lt;br /&gt;Congratulations, you're a maintenance programmer.  As a maintenance programmer, you had to do something that I imagine manages to elude even more so-called developers than writing FizzBuzz - reading (and more importantly, understanding) code.&lt;br /&gt;My tweak on the FizzBuzz script is the following snippet.  Along with it, I pose the (very hopefully hypothetical) question - "I found this function in the code base the other day and 'z' obviously isn't very meaningful.  Could you walk me through how you'd go about figuring out what to rename it?"&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre wrap=""&gt;public static void z(int[] x)&lt;br /&gt;{&lt;br /&gt;   for(int i = x.Length - 1; i &gt; 0; i--)&lt;br /&gt;   {&lt;br /&gt;       for(int j = 0; j &lt; i; j++)&lt;br /&gt;       {&lt;br /&gt;           if(x[j] &gt; x[j + 1])&lt;br /&gt;           {&lt;br /&gt;               int t = x[j];&lt;br /&gt;               x[j] = x[j + 1];&lt;br /&gt;               x[j+ 1] = t;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To get it out of the way, yes, it's a bubble sort written in a C-like language.  At this point, let me just state for the record, I think you're all better than me.&amp;lt;/Seinfeld&amp;gt;&lt;br /&gt;So why is this so much better than having someone write FizzBuzz?  Think about it - if they can't write FizzBuzz, they can't read it either.  If they blow either question, interview over.  If they get FizzBuzz right, where do you go from there?  It's a binary question (only right or wrong) and those aren't useful for interviews where you're trying to get a feel for the person.&lt;br /&gt;With Function Z, you're weeding out the FizzBuzz failures (and more of them), plus you're getting some lightweight insight into their thought processes, plus bonus insights once they've figured out that it's a sort function.&lt;br /&gt;For example...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Are they the prosaic type, questioning whether or not the language provided a native Sort() method on the integer array and why it wasn't used?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Are they a &lt;a href="http://c2.com/cgi/wiki?NotInventedHere"&gt;Not Invented Here&lt;/a&gt; cowpoke, quick to point out that you should rewrite it as a quick sort and speed things up (I can see how this feels like a trick question for an interview, but I get nervous about people who make changes with that little context (on the other hand, encapsulation and wow I wouldn't even hire myself, would I?))?&lt;/li&gt;&lt;li&gt;Are they the type that wants to leave everything better than they found it, cleaning up the variable names as they go along?&lt;/li&gt;&lt;li&gt;Do they ask for the unit tests to accompany it?!?!??!?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I can see how either FizzBuzz or Function Z can spin into the ugly territory of "monstrous interview question I ask to make them feel like a dick", so I implore you to keep your hypothetical functions short and sweet.&lt;br /&gt;So who else has some deceptively simple interview techniques?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-6758854693168495356?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/6758854693168495356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=6758854693168495356' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6758854693168495356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/6758854693168495356'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/06/rethinking-fizzbuzz-function-z.html' title='Rethinking FizzBuzz - Function Z'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5771712890638368173</id><published>2007-06-03T22:15:00.000-07:00</published><updated>2007-06-04T15:26:23.381-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interface'/><category scheme='http://www.blogger.com/atom/ns#' term='cycling'/><title type='text'>Of bicycles and software</title><content type='html'>Thanks to getting hit last year by a guy in a pick-up truck who failed to yield, leaving me with a broken collarbone and multiple broken ribs, I've had a long absence from cycling.  My old bike's still at the police station (maybe) and I've finally gotten a new one, which is a good thing - I've been crawling out of my skin to get back out on the roads and trails.&lt;br /&gt;It's a gorgeous new bike.  I'll stop short of calling it a work of art, but it sure is pretty.  In just about every way I can quantify, it's better than my old bike.  Yet despite this &lt;span style="font-style: italic;"&gt;undeniable fact&lt;/span&gt;, I find myself not loving my bike and longing for my old bike, the one that I swore I'd never ride again.&lt;br /&gt;It's piddly little things, like the derailleur levers being set up differently.  The changes in frame geometry.  Sticky rubber grips instead of hard rubber ones.  All these seemingly inconsequential little things add up to me not being as in love with my new bike as I should be yet.  I'm out on it and "did my old bike climb faster than this one?" and "is this new frame &lt;span style="font-style: italic;"&gt;too rigid&lt;/span&gt;?" and other heresies run through my mind.&lt;br /&gt;&lt;br /&gt;As I'm out riding, this brings to mind being down at the big corporate headquarters a while back, picking people's brains for this new application we're going to be building.  They're showing us how they set up things on their end and things are, keeping it sophisticated, execrable.&lt;br /&gt;The interface sometimes locks up, but you have to wait to see if it unlocks.  If it doesn't, you have to close out because it probably means something's wrong and you'll lose your work.  If you've gotten past this step, there's no going back and it means you have to re-do hours of keying because you can only export from System A to System B once.  Hoops must be jumped through and chickens sacrificed just about every step of the way.&lt;br /&gt;I see obvious little fixes that should be pretty simple and big time-savers and I run them by them  They get uncomfortable with the propositions and the answers all basically boil down to "we can't do it your way because we do it our way."  Of course, I scoff to myself all the way home because &lt;span style="font-style: italic;"&gt;wow they're lifers&lt;/span&gt; but then again, the first thing I do with Windows XP is turn off the bells 'n whistles and get back to the Windows 2000 interface that I'm used to.&lt;br /&gt;&lt;br /&gt;When it comes to interfaces, doing things right the first way obviously should be your first choice.  Once it's been deployed and users have been banging away on it for years, take some time and reconsider overhauling the UI to use the newest and shiniest widgets you can find out there.  There's a balance to be struck and you need to be smart about it.&lt;br /&gt;No matter how god-awful the old UI was or how much pain it caused (and continues to cause), you're going to make users unhappy by changing things around.  You think you're bringing joy into the world, but steel yourself for the onslaught of angry-grams when you release your update.&lt;br /&gt;I look at pieces of the application and some parts are flat-out cringeworthy and I'd love to change them to hide my shame, but I have to ask myself - are these changes making me happy or are they making my users happy?&lt;br /&gt;&lt;br /&gt;If you're sure you've made the right choice, stick with it.  After all, some of your users are knuckle-draggers who do everything they can to make their new OS look like their old one and resent their bikes for little details that make damned near no difference and distrust applications that don't crash on them if they do something "wrong".&lt;br /&gt;What do they know?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5771712890638368173?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5771712890638368173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5771712890638368173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5771712890638368173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5771712890638368173'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/of-bicycles-and-software.html' title='Of bicycles and software'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8134650775413815569</id><published>2007-05-29T15:45:00.002-07:00</published><updated>2007-06-05T19:57:17.471-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management'/><category scheme='http://www.blogger.com/atom/ns#' term='bonuses'/><title type='text'>Bonuses considered harmful</title><content type='html'>Did I nod off or something?  The meeting had started out well enough, a mind-numbing Powerpoint talking about the methodically developed rewards structure and how there were professionals with years of experience deploying &lt;span style="font-weight: bold;"&gt;this very bonus structure&lt;/span&gt; to Fortune Yadda Yadda companies but the presentation over, people started asking questions, and that's where things started going hella bad.&lt;br /&gt;The company I work for started out its life as a start-up and was eventually bought out by a much larger company.  When the corporation's new management came in, they gave us the  feel-good bill of goods: you're the best of the best, entrepreneurial spirit, turn on a dime, yadda yadda.&lt;br /&gt;But the honeymoon had to end sooner or later and this wasn't getting pretty, for one big reason - people had counted on the fact that we were, after all, the best of the best, and this naturally meant that when it came time for the annual bonuses and raises, they were going to &lt;span style="font-style: italic;"&gt;make bank&lt;/span&gt;.  Except now, the ugly reality was setting in - deadlines we had no say in defining had been blown and there had to be repercussions.  Oh, and you're already being paid over market value, so don't hold your breath on that raise either.&lt;br /&gt;Nobody's buying it.  The mood's getting palpably hostile.&lt;br /&gt;Reiteration.  This works for big companies and my hands are tied.&lt;br /&gt;Some people resigned themselves to reality, others just... resigned.&lt;br /&gt;&lt;br /&gt;So I've seen what can go wrong when you dangle the carrot in front of people.  But for myself, I just don't care about the carrot.  I was excited when I got a big raise a few years back, but I've been given bonuses multiple times since and have been completely unenthused by them.&lt;br /&gt;I must be an insane person, right?  I live in a capatalist/consumerist society; I should love money and being given more of it should make me excited, right?&lt;br /&gt;After all, when you get down to it, I'm just a developer.  I took a couple of management classes in college (I promptly forgot everything except for the goofy terminology like &lt;span style="font-weight: bold;"&gt;ROI&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;core competency&lt;/span&gt; and other bits and pieces I sprinkle liberally when I'm being a dick) so what do I know about bonuses?  &lt;span style="font-style: italic;"&gt;Very smart people&lt;/span&gt; came up with the bonus structure and everyone understands the stick and the carrot so I must be an aberration.&lt;br /&gt;Except for the fact that, thank god, I'm not the only person that thinks this way.  Alfie Kohn's written books challenging conventional wisdom on bonuses and strict management structure, and there's &lt;a href="http://www.alfiekohn.org/business.htm"&gt;a few of his papers up on his internets site&lt;/a&gt;.&lt;br /&gt;Go read his papers and you'll find the same theme repeating itself - bonuses (or, in way-smarter-than-me parlance, "extrinsic inducements") have been proven time and time again to fail to work.  At best, you get an initial boost, but given a little time, the problems that bonuses create (making co-workers adversaries rather than, well, co-workers by breeding feelings of resentment to name one) quickly outweigh any of the quick-fix wins that you may have realized from them.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;That rewards &lt;i&gt;can't&lt;/i&gt; get us what we want     is a heretical idea, but it emerges ineluctably from a critical     analysis of motivation and work.&lt;br /&gt;- Alfie Kohn, Challenging Behaviorist Dogma&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;About two dozen studies from the     field of social psychology conclusively show that people who expect     to receive a reward do not perform as well as those who expect     nothing. This result, which holds for all sorts of rewards, people     and tasks, is most dramatic when creativity is involved.&lt;br /&gt;- Alfie Kohn, For Best Results, Forget the     Bonus&lt;/blockquote&gt;Still not buying it?  Let me try the metaphor that came to me when I was out cycling.&lt;br /&gt;Why was I so much happier to get a cheap-o t-shirt with some of the in-jokey slogans celebrating the release of our product than I was to get thousands of dollars of bonuses?&lt;br /&gt;Growing up, I had two hypothetical Aunts, Annie and Betty.  Every year for my birthday, Aunt Annie gave me a little toy.  Every year, Aunt Betty gave me a crisp twenty dollar bill.&lt;br /&gt;Whose present would you look forward to and appreciate more - the one that shows that she's spent time figuring out what a kid your age would want or the one that shows that she's got a wallet and maybe an iron?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8134650775413815569?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8134650775413815569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8134650775413815569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8134650775413815569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8134650775413815569'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/bonuses-considered-harmful.html' title='Bonuses considered harmful'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-7253050322593409161</id><published>2007-05-26T18:24:00.000-07:00</published><updated>2007-05-31T18:18:30.914-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements documents'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><title type='text'>The case for McMansion architects (part 2)</title><content type='html'>So I think I might even have reasonably established that handing off a specification to an architect (no matter how good) is necessarily going to be nothing but an unmitigated disaster if you're expecting something arable the first go-round.&lt;br /&gt;But these McMansions, these big, generic, samey houses.  These enterprise software applications, this big, onerous, pay a million and pay a million more for consultants to get something nominally useful that no one likes using programs.  Why do they get built in the first place?&lt;br /&gt;I keep coming back to a PBS Frontline program called &lt;a href="http://www.pbs.org/wgbh/pages/frontline/shows/persuaders/"&gt;The Persuaders&lt;/a&gt; and in particular, the interview with &lt;a href="http://www.rapailleinstitute.com/"&gt;Clotaire Rapaille&lt;/a&gt;, a French cat who isn't afraid to pose like he's in a rap video in front of his mansion with his cars (seriously, check the picture on the front page of his internets site) and proffer a bastardization of Jungian archetypes and Lacanian linguistic dynamics for &lt;span style="font-style: italic;"&gt;mad profit&lt;/span&gt;.&lt;br /&gt;As he explains in the program, the car companies came to him, looking to get in touch with their consumers and give them something that would jump off the lots, so he started interviewing people and came to a revelation - bigger automobiles, taller off the ground, with tinted windows were "code" for "wealth", "power" and "domination."&lt;br /&gt;Rapaille talks about drilling through the mammal brain and speaking directly to the lizard brain.  John Coltrane put it more eloquently - &lt;i&gt;"The emotional reaction is all that matters. As long as there is some feeling of communication, it isn't necessary that it be understood."&lt;/i&gt;  Rapaille sure was on to something with making them SUVs bigger and taller and whatnot, because they provoke gut responses in people.  You ask people who drive them why they drive them and they'll tell you "because I feel safer in them" and it really doesn't matter if you were to put the crash tests that say otherwise in front of them.  They're safer and that's all there is to it.  You ask me, who would just as soon drive a goofy European-small car, about them and I hate them because they're gaudy monuments of conspicuous consumption.&lt;br /&gt;But underneath my upturned nose, I'll admit it - there's the seeds of jealousy in there.  I can't explain why, either.  I've driven them and hate driving them.  I don't like being up high, they handle like tanks and jesus christ the gas milage.  But still, when I'm driving behind some jackhole and I can't see through the blacked-out rear window to the car in front of them, wouldn't it be nice to be able to see the guy in front of them?&lt;br /&gt;Why the McMansions?  In this context, I think it's easy to see where the infatuation with more house and less soul than you need comes from.  For the same money you're putting out on a McMansion (and probably more because deviation from the crowd is gonna cost you), you're ultimately getting "less" house.  There's safety in numbers and everyone else is doing it, so it takes an extra dose of courage to get it done.&lt;br /&gt;You can't define soul, but square footage is easy to quantify.&lt;br /&gt;Think about it - deep down inside, you've got that sense of unease gnawing at your stomach.  You're spending more money for ultimately less house.  The garish abomination that they're building is more than they need, isn't built for them but rather some generic approximization of them, they can't afford it, but... they're getting a whole lot of square footage and maybe I could make it my own by decorating it nicely and choosing the fixtures I'll have the place built out with?  It's easy to slide back to the road more travelled.&lt;br /&gt;The lowest common denominator is hard to argue with for a reason.  IBM may not be the greatest, but nobody ever got fired for buying it.  Budweiser and McDonald's suck, but won't you come off like a snob if you tell your friends you want to get something better?&lt;br /&gt;I'd like to think that I have the courage to admit to myself and others that I'm OK with smaller and better.  You probably have the same courage... but do we have the courage?&lt;br /&gt;Product development comes up with a giant specification.  You may have the courage to question whether a service-oriented n-tier architecture implemented in .Net 2.0 and redundant Oracle databases communicating with your Oracle Financials OLTP system with the data cached in XML for quick retrieval and the requisite smattering of patterns talk makes any sense whatsoever for this hypothetical product, but how convincing of an argument can you make to the contrary&lt;br /&gt;Product development probably isn't really interested in hearing that these dozens of features that they've spent weeks and months painstakingly realizing and documenting probably aren't needed.   Management isn't going to be sold on you telling them that less being more - they see their career riding on hundreds of pages worth of specification and who is this programmer to tell me that less is more and we don't need these features that product development does? We paid that architect good money for a good reason.&lt;br /&gt;McMansions, SUVs and &lt;span style="font-weight: bold;"&gt;enterprise class software&lt;/span&gt; are all about us being sold what we want instead of what we need.  It awfully hard to argue with the inner child that's having problems rationalizing away the fact that we're paying 15 percent more money for 15 percent less square footage.   Peopleware costs a boatload and wow look at all of the things that it can do (I've tried to figure out what it is and near as I can figure, they've managed to assemble what I can only describe as a Rorschach application), so it can obviously do what we want (nevermind that we need to use the thing and that may not be possible).  It's hard enough to argue with our inner child; you get a room full of inner children together and the odds of common sense rearing its pretty head rapidly approach zero.&lt;br /&gt;A quote I've heard that's apt - "in a community of saints, we are all sinners."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-7253050322593409161?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/7253050322593409161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=7253050322593409161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7253050322593409161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/7253050322593409161'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/case-for-mcmansions-part-2.html' title='The case for McMansion architects (part 2)'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-5575191997192503413</id><published>2007-05-26T12:59:00.000-07:00</published><updated>2007-05-26T13:53:35.000-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements documents'/><category scheme='http://www.blogger.com/atom/ns#' term='software architecture'/><title type='text'>The case for McMansion architects (part 1)</title><content type='html'>So I'm reading an &lt;a href="http://weblog.raganwald.com/2007/05/not-so-big-software-application.html"&gt;interesting piece decrying "McMansion" software architecture&lt;/a&gt; and totally nodding my head.  Raganwald's a better writer and smarter than I am (PLEASE DON'T HATE ME MR. WALD) and given that a recurring theme in his posts is casting "best practices" aside and being brutally intellectually honest about what you're doing and how it's failing and can be ameliorated, he's right.  But as the devil's advocate with a massive failure of vision, here I go sticking my foot in my mouth.&lt;br /&gt;It's an interesting article to be sure, but at the end of the day, it feels like it's restating Brooks' thesis on essential and accidental difficulties in software development (yes I just reread &lt;u&gt;The Mythical Man-Month&lt;/u&gt;, what of it?).&lt;br /&gt;There's a part of me that's totally nodding in agreement at being saddled with cookie-cutter&lt;br /&gt;concepts and then there's another part of me that's scratching my head about what exactly is wrong with using databases and XML and all the other unsexy (proven) technologies that the anonymous architect has proposed to bring the app from a "telephone book sized specification" of requirements to an implemented product.  There's a part of me that's giving an e-high five for sticking it to consultants who are paid too much to use a metric ton of buzzwords to not quite tell you what you already know and a part of me that's wondering what exactly is wrong with using COTS products and technologies since I'm not a world-class developer and don't work with world-class hackers and maybe I won't see as many exciting things on the road more travelled, but I won't fall off a cliff either.&lt;br /&gt;I honestly feel bad for the architect.  Think about it for a second - a specification that probably runs upwards of a hundred pages.  I haven't seen the spec or the proposal, but I feel safe in asking the question - who could possibly put together a proposal that would sanely satisfy something like that?  If I'm Raganwald, I'm probably going to outwardly scoff to anyone unfortunate enough to listen to me because I'm an asshole like that, but at the same time I've got to be happy that there's progress that's been made.  OK, the initial draft sucks and the architect looks like a chump and here's a dozen reasons why, but at least we're moving from something proposed by a group of people (I doubt it was one person who was put together that specification; I'm assuming that it was spec'd by a committee and written by a couple of people) into a proposal that I can digest and critique and iteratively improve upon to a point where we have a good enough idea of what we're all talking about that we can actually make something.&lt;br /&gt;The initial architecture proposal sucks?  I'd be astonished if it didn't.  Using XML is the wrong decision?  Thank god we're far enough along that I can definitively say that.  That's better than we were a telephone book ago.&lt;br /&gt;Above and beyond the obvious problem (a mammoth spec), in handing it to an outside entity, you're dealing with some unspoken problems.  That specification is ostensibly the crystallized desires of a group of people, but hiding deep beneath and in-between the lines are the unspoken desires of people that never made it in there.  How much of what ended up on the cutting floor could be picked up and stitched together into a fabric that details the essence of what they're after?  Was the spec handed off to a single person to trim the fat off of everything?  Did they have the courage to ask the terrifying question that nobody wants to ask - &lt;span style="font-style: italic;"&gt;do we really need to develop this&lt;/span&gt; and the added fortitude and singular vision to come to that conclusion on their own?&lt;br /&gt;Maybe I'm just missing the bigger point because at the end of the day, I doubt I'll ever be the Le Corbusier of software development and I'm just totally projecting here.&lt;br /&gt;I believe that it is possible to overcome the fantasy/reality impedance, but nobody's going to be happy when you do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-5575191997192503413?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/5575191997192503413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=5575191997192503413' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5575191997192503413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/5575191997192503413'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/case-for-mcmansion-architects-part-1.html' title='The case for McMansion architects (part 1)'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-2247554043070221407</id><published>2007-05-24T12:55:00.000-07:00</published><updated>2007-05-26T12:59:33.894-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='text'/><category scheme='http://www.blogger.com/atom/ns#' term='wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Supercharge your to-do list</title><content type='html'>Over on the sinister secretGeek log, Mr. Geek's &lt;a href="http://secretgeek.net/text_todo.asp"&gt;singing the praises of a text-driven todo file&lt;/a&gt; as a make-shift means of communication between multiple (two) developers through a source repository.&lt;br&gt;I've done the text todo file thing in the past too - it's drop-dead simple and it works.&amp;nbsp; I'm sure some people are aghast, but do you really need or want to fire up Excel or Project to track tasks?&amp;nbsp; Do you want to spam one another with e-mails tracking the itches you're scratching as well as what you're getting done?&amp;nbsp; It's imperfect, but it's easy and it works with a couple people.&lt;br&gt;That said, the concept of a shared text file is sort of... barbaric.&amp;nbsp; We live in the age of The Internets and The Internets have newer and better and shinier for us.&amp;nbsp; A wiki would do a good job of replacing the t-file; you can tag items and search and find stuff, plus it has built-in revision control so you can easily cut and paste or clean items off of your pages and they'll be available to you later if you didn't mean to delete them.&amp;nbsp; Not that I'd ever make a mistake like that.&lt;br&gt;But who wants to set up a wiki?&amp;nbsp; You've got to install the package, you've got to work out the dependencies and then have a way of securely publishing it so that only the right people can see it.&amp;nbsp; For two people, this absolutely feels like overkill.&amp;nbsp; But still... a wiki sure would be nice.&lt;br&gt;So, uh.&amp;nbsp; Why not &lt;a href="http://www.tiddlywiki.com/"&gt;use TiddlyWiki instead&lt;/a&gt;?&lt;br&gt;For those of you not hip to it, TiddlyWiki is a standalone wiki, implemented in an HTML file and it works splendidly.&amp;nbsp; There's a GTDTiddlyWiki out there if you've drank the GTD Kool-Aid (I haven't).&amp;nbsp; I don't know that it has all the internally-implemented revision control that a more full-fledged wiki has, but it does have tags and search features built right into it and it requires nothing more than a browser (it's just an HTML file, guy) but if you sync it up with your source repository often enough, hey wow you've got revision control there.&amp;nbsp; Nothing more to futz with and you're still sharing a text file between developers.&amp;nbsp; It's just a shinier text file.&lt;br&gt;Or you could hang back in the stone age.&amp;nbsp; Hey, your call.&lt;br&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-2247554043070221407?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/2247554043070221407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=2247554043070221407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2247554043070221407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/2247554043070221407'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/supercharge-your-to-do-list.html' title='Supercharge your to-do list'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-8906473035201095050</id><published>2007-05-17T12:53:00.000-07:00</published><updated>2007-09-07T15:26:56.356-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>I have a man-crush on Subversion.</title><content type='html'>I've got a big problem and I'm not afraid to admit it, so here it is - I've become obsessed with Subversion.  For honest, really.&lt;br /&gt;I'm a .Net developer, so this is sort of a problem - why not use Visual SourceSafe like everyone else?  I mean, it's good, right?&lt;br /&gt;I guess in the sense that it sort of works, yeah.  But on Windows, the combination of Subversion and TortoiseSVN is &lt;i&gt;so very very nice&lt;/i&gt; that once you go with Subversion (SVN), you won't look back.  Actually, strike that.  I guess you might look back fondly on VSS like you do other apps that took their design pointers from their fellow Windows 3.11 programs and that cause something just short of physical pain used over a WAN connection if you'd like.&lt;br /&gt;If you're a Windows person, installing Subversion can be a bit of a mystery.  You'll ask The Google about it and it will tell you odd things like you need some SVN service (that has been deprecated) and eventually you'll find &lt;a title="Subversion's l33t t-file on installing a Windows Service" href="http://svn.collab.net/repos/svn/trunk/notes/windows-service.txt"&gt;a text file&lt;/a&gt; that explains how to install SVN as a Windows service with the newer revisions... sort of.  But if you're like me, you don't want to read a poorly-written, incomplete text file that doesn't apply to you, you want &lt;b&gt;results&lt;/b&gt; and you want them now.&lt;br /&gt;So here's how you install Subversion 1.4.3 (the current version) on Windows.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Hit up &lt;a title="SVN" href="http://subversion.tigris.org/"&gt;Subversion's site&lt;/a&gt; and download the Windows version of the application (you want the 1.4.3 setup executable)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to &lt;a title="Windows Explorer extension for SVN" href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN's internets site&lt;/a&gt; and ask it nicely for a copy of TortoiseSVN&lt;/li&gt;&lt;ol&gt;&lt;li&gt;If you're running Windows 2000 and not XP/Server 2003, now would be a good time to &lt;a title="SC.exe from the Windows 2000 Resource Kit" href="ftp://ftp.microsoft.com/reskit/win2000/sc.zip"&gt;download a copy of SC.exe&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Install Subversion (into c:\subversion rather than underneath Program Files), then install TortoiseSVN (reboot if it asks you to because we are, after all, running Windows)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When you're ready, drop to a command prompt (win+r-&amp;gt;CMD) and issue the following commands&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;tt&gt;cd\&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;tt&gt;svnadmin create svnrepos&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;tt&gt;sc create Subversion binpath= "c:\subversion\bin\svnserve.exe --service --root c:\svnrepos" start= auto depend= tcpip&lt;/tt&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;???&lt;/li&gt;&lt;li&gt;Profit!&lt;/li&gt;&lt;/ol&gt;So what did you do there?  Well, you created a new SVN repository (the place where the files go) named svnrepos directly under the root.  And then you used SC, service controller, to install an auto-starting instance of the SVN server as a Windows service.&lt;br /&gt;What now?  Fire up TortoiseSVN's repository browser (open Explorer, right-click on something and it'll be under TortoiseSVN's new context menu) and connect to "svn://localhost".  You should see an empty repository and that means that the magic is there waiting for you.  You can create directories here or you can import a directory (put it under revision control) and create and add directories.&lt;br /&gt;Still not sold?  Here's some of the reasons that I made the jump.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Group-based, directory-level access control&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Imagine - QA can look, but can't touch (and you can't touch their scripts either)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Pre- and post-commit hooks&lt;/li&gt;&lt;ol&gt;&lt;li&gt;No more check-ins without comments attached; the server swats anyone who tries it (yes, that's a pet peeve of mine)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;RSS feeds&lt;/li&gt;&lt;ol&gt;&lt;li&gt;VSS has a service that someone else wrote that sucked a little less when I made it multithreaded, but it still sucked (no offense as I was impressed by the mere fact that it existed).  SVN's is sane and performant.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Statistics&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Lines of code!  Code churn!  Developer stats!  Way more fun than it should be for the procrastinator in all of us.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;Don't you want to feel like you've accomplished something today?  Get your Subversion on, kids.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-8906473035201095050?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/8906473035201095050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=8906473035201095050' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8906473035201095050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/8906473035201095050'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/i-have-man-crush-on-subversion.html' title='I have a man-crush on Subversion.'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5322535968700669808.post-4266814164897682970</id><published>2007-05-10T12:45:00.000-07:00</published><updated>2007-05-26T13:55:20.733-07:00</updated><title type='text'>10 I AM GOOD AT BASIC 20 GOTO 10</title><content type='html'>HELLO WORLD&lt;br /&gt;I'm Dave, your, uh.  Host here?&lt;br /&gt;I'm a software developer from the wilds (OK, not really the wilds) of New Hampshire.&lt;br /&gt;I'm embarassed by the code I wrote 3 months ago, let alone last year, but what can you do?  Live and learn and go out there with a chip on your shoulder because there's always room to grow.&lt;br /&gt;I'd like to think that after close to a decade being gainfully employed hitting keyboards, I've finally wrapped my head around the software development process a little.  And in wrapping my head around it, I've seen that there's forces beyond beautiful code that determine whether the software I'm helping to architect and develop works or is a stillborn mess.&lt;br /&gt;I'm trying to come to terms with that and the ugly sensation that keeping up with software development is a red queen's race and that maybe if I had some say in how the software was managed maybe I'd be able to do something about it?&lt;br /&gt;I like music.&lt;br /&gt;I like to read.&lt;br /&gt;I like to ride my bike.&lt;br /&gt;I like to not get hit by trucks when I'm riding my bike.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5322535968700669808-4266814164897682970?l=48klocs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://48klocs.blogspot.com/feeds/4266814164897682970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5322535968700669808&amp;postID=4266814164897682970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4266814164897682970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5322535968700669808/posts/default/4266814164897682970'/><link rel='alternate' type='text/html' href='http://48klocs.blogspot.com/2007/05/10-i-am-good-at-basic-20-goto-10.html' title='10 I AM GOOD AT BASIC 20 GOTO 10'/><author><name>Dave Solomon</name><uri>http://www.blogger.com/profile/05774470881611185492</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
