<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Hacker Boss</title> <atom:link href="http://hackerboss.com/feed/" rel="self" type="application/rss+xml" /><link>https://hackerboss.com</link> <description>Developing software and managing development teams.</description> <lastBuildDate>Thu, 16 Sep 2010 19:57:26 +0000</lastBuildDate> <generator>http://wordpress.org/?v=</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Do You Write Legacy Code?</title><link>https://hackerboss.com/legacy-code/</link> <comments>https://hackerboss.com/legacy-code/#comments</comments> <pubDate>Wed, 08 Sep 2010 12:39:02 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1781</guid> <description><![CDATA[In his foreword to Working Effectively with Legacy Code by Michael C. Feathers, Robert C. Martin says:Legacy code.  The phrase strikes disgust in the hearts of programmers.  It conjures images of slogging through a murky swamp of tangled undergrowth with leaches beneath and stinging flies above.  It conjures odors of murk, slime, [...]Related posts:<ol><li><a
href='https://hackerboss.com/why-write-code-when-you-can-remove-some/' rel='bookmark' title='Permanent Link: Why Write Code When You Can Remove Some?'>Why Write Code When You Can Remove Some?</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p><span
class="drop_cap">I</span>n his foreword to <a
href="http://www.amazon./dp/0131177052?tag=hashedbits-20">Working Effectively with Legacy Code</a> by Michael C. Feathers, Robert C. Martin says:</p><blockquote><p> Legacy code.  The phrase strikes disgust in the hearts of programmers.  It conjures images of slogging through a murky swamp of tangled undergrowth with leaches beneath and stinging flies above.  It conjures odors of murk, slime, stagnancy, and offal.  Although our first joy of programming may have been intense, the misery of dealing with legacy code is often sufficient to extinguish that flame.</p></blockquote><p><a
href="http://dilbert.com/strips/comic/2006-12-08/" title="Dilbert.com"><img
src="http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/00000/1000/400/1438/1438.strip.gif" border="0" alt="Dilbert.com" /></a></p><p>Besides serving as inspiration for poetic descriptions of wetlands and humorous sequences of drawings, legacy code is also something you don&#8217;t want in your Emacs. But how can you prevent it from getting there?  At what point does code turn from &#8220;perfectly good&#8221; or at least &#8220;I guess it&#8217;s OK&#8221; into &#8220;legacy crap&#8221;?  We need to define what &#8220;legacy code&#8221; is.</p><p>Many people will characterize legacy code as simply old, but that&#8217;s not a very practical definition.  Good code doesn&#8217;t turn into legacy code on a rainy Tuesday afternoon at 2:17pm.  A better definition gives us some clues on how to prevent code from <i>becoming</i> legacy code.   You can&#8217;t stop time.</p><p>Perhaps legacy code is a feeling.  It&#8217;s the feeling that the code is too hard to approach, risky to change, and difficult to understand.  This makes for a slightly better definition, because it suggests some things to avoid (don&#8217;t write crappy code, duh!).  However, basing a definition like this on feelings is a bit&#8230; scary.</p><div
style="float: right;"> <a
href="http://www.amazon./dp/0131177052?tag=hashedbits-20"><img
src="http://ecx.images-amazon.com/images/I/51RCXGPXQ8L._SL500_AA300_.jpg"></a></div><p>In the book, Feathers gives a very simple definition:</p><blockquote><p> To me, legacy code is simply code without tests.</p></blockquote><p>This is a pretty good definition. Tests make the code simpler to approach, less risky to modify, and easier to understand.  Tests protect against the very things that make legacy code legacy.</p><p>With this definition, we arrive at a shocking realization: <strong>someone in your team could be writing legacy code <i>right now</i>.</strong></p><p>Do <i>you</i> write legacy code?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/why-write-code-when-you-can-remove-some/' rel='bookmark' title='Permanent Link: Why Write Code When You Can Remove Some?'>Why Write Code When You Can Remove Some?</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/legacy-code/feed/</wfw:commentRss> <slash:comments>13</slash:comments> </item> <item><title>Why Apple Doesn&#8217;t Want Your App</title><link>https://hackerboss.com/why-apple-doesnt-want-your-app/</link> <comments>https://hackerboss.com/why-apple-doesnt-want-your-app/#comments</comments> <pubDate>Mon, 12 Apr 2010 11:30:55 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1726</guid> <description><![CDATA[
So you make an iPhone app, and it doesn&#8217;t enjoy the success you think it deserves.  Or you make an app, and you create a technology framework on the side, and they ban your framework, and your app and framework don&#8217;t enjoy the success you think they deserve.  Here&#8217;s why.
First, a detour to [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/why-apple-doesnt-want-your-app/" title="Permanent link to Why Apple Doesn&#8217;t Want Your App"><img
class="post_image alignnone" src="http://hackerboss.com/pics/rejected.jpg" width="423" height="284" alt="Post image for Why Apple Doesn&#8217;t Want Your App" /></a></p><p><span
class="drop_cap">S</span>o you make an iPhone app, and it <a
href="http://gedblog.com/2009/09/28/losing-ireligion/">doesn&#8217;t enjoy the success</a> you think it deserves.  Or you make an app, <em>and</em> you create a technology framework on the side, and they <a
href="http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler">ban your framework</a>, and your app and framework don&#8217;t enjoy the success you think they deserve.  Here&#8217;s why.</p><p>First, a detour to clarify what Apple makes money from.  For perspective, let&#8217;s look at Microsoft first.</p><p>Microsoft is, and has pretty much always been, in the business of selling Windows.  Microsoft wants PCs to be cheap, so they can sell more Windows.  The whole PC and peripherals market is fiercely competed and the profit margins for hardware vendors are really low.  That&#8217;s been working out nicely for Microsoft, since most PCs still ship with a version of Windows included, and Windows is making tons of money.</p><p>Microsoft is also in the business of selling Microsoft Office.  In 2008, <a
href="http://www.tannerhelland.com/commentary/tech/where-does-microsoft-make-its-money/">Microsoft made as much money with Office as it did with Windows</a>.  Kind of like the fax machine was (and still is in some parts of the world), Office is the standard method of information interchange in the business world.  Just like the fax machine, you need Office because everyone else has it, too.</p><p>Apple, on the other hand, is in the business of selling hardware.  Despite their recent high-profile focus in the iPhone OS software, <strong>Apple is very much a hardware company.</strong></p><p>So let&#8217;s get this straight: Apple is not making a lot of money off the App Store. <strong>Apple is not even trying to make a lot of money off the App Store.</strong></p><p>Apple wants apps to be a cheap commodity.  When there are a lot of cool apps around, and they cost next to nothing, it really makes you want to go buy an iPhone, doesn&#8217;t it? <strong>Useful, cheap apps sell more iPhones.</strong> Microsoft is the opposite: cheap hardware sells more Windows.</p><p>In this light, I find it strange how Apple is conducting some of their business towards the community of independent software developers.  The latest <a
href="http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler">ban on using anything but Objective C, C, C++ for native apps</a>, for example, strikes me as quite strange.  By which I mean it strikes me as completely idiotic.  Banning programmers&#8217; favorite tools is stuff which makes <a
href="http://tuomaspelkonen.com/2010/04/rip-lua-programming-on-iphone/">talented developers call it quits</a> and <a
href="http://techcrunch.com/2009/11/11/joe-hewitt-developer-of-facebooks-massively-popular-iphone-app-quits-the-project/">stop working on the iPhone platform</a>.  How can that possibly be in Apple&#8217;s business interests?</p><p>Many iPhone developers seem to be driven by the &#8220;publish an app and get rich quick&#8221; myth.  However, the app market is fiercely competed.  In order to make any significant money on the App Store, your app must be really good, one of the first of it&#8217;s kind (if not the first), and you must be lucky.  This is App Store poker.  It&#8217;s like trying to win the World Series of Poker by entering a satellite freeroll.  It can happen, but I&#8217;m willing to be it won&#8217;t happen to <em>you</em>.</p><p>Is App Store poker enough to maintain a steady influx of apps to iPhone OS?  Oh yes, it is.  It is more than enough.  Like with their hardware, <strong>Apple wants the apps to be about quality, not quantity.</strong> <a
href="http://scobleizer.com/2010/04/11/is-2011-like-1994-for-apple-twitter-facebook-and-the-web/">Robert Scoble says</a>:</p><blockquote><p>So, what does Apple need? Is it more apps? No way. At 130,000 apps Apple already has enough apps to keep a sizeable lead for years over its competitors like Google’s Android OS.</p><p>No, what Apple needs is better quality apps. So, does Apple care about templated apps or ones developed in Flash or some other cross-device language/system? No way.</p></blockquote><p>Apple doesn&#8217;t want your app because your app sucks.  Probably.  Statistically, anyway.  Most apps aren&#8217;t anything special, why should yours be any different?</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/why-apple-doesnt-want-your-app/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Is Your Regex Matcher Up to Snuff?</title><link>https://hackerboss.com/is-your-regex-matcher-up-to-snuff/</link> <comments>https://hackerboss.com/is-your-regex-matcher-up-to-snuff/#comments</comments> <pubDate>Mon, 15 Mar 2010 21:13:38 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[regex]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1694</guid> <description><![CDATA[Did you know that your regex matching library may suck? Most libraries do, in certain circumstances, suck exponentially.  This came to me as a great suprise when, a long time ago in the olden days before Google, iPods, and salmon skin leather, I was researching regex matching engines hoping to find a good one [...]Related posts:<ol><li><a
href='https://hackerboss.com/approximate-regex-matching-in-python/' rel='bookmark' title='Permanent Link: Approximate Regex Matching in Python'>Approximate Regex Matching in Python</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p><strong>Did you know that your regex matching library may suck?</strong> Most libraries do, in certain circumstances, suck exponentially.  This came to me as a great suprise when, a long time ago in the olden days before Google, iPods, and salmon skin leather, I was researching regex matching engines hoping to find a good one for use in a real-time system.</p><p>I&#8217;ll illustrate with a dusty ten-year-old picture from my Master&#8217;s Thesis:<br
/> <img
src="http://hackerboss.com/pics/TNFA-speed.png"></p><p>Horror!  When I showed this to my colleagues, they didn&#8217;t believe it.  Everyone just sort of assumed that the regex matchers they were using every day would, you know, work.  The lesson here is that <strong>some regex matchers take potentially exponential time to find a match, while others always take linear time.</strong></p><p>This picture may be over ten years old, but the world of regex matchers hasn&#8217;t really changed a whole lot.  Virtually all libraries included in programming languages or their standard libraries use so called &#8220;backtracking&#8221; matchers and suffer from this performance issue.  Python, Perl, PCRE, PHP, Java, and Ruby all come with a backtracking matcher.  An infinite number of combinations of regexes and input strings exist which completely choke these matchers.  For a detailed explanation, I recommend <a
href="http://swtch.com/~rsc/regexp/regexp1.html">Regular Expression Matching Can Be Simple And Fast</a> by Russ Cox, where he also has these better pictures (note difference in y axis scale in the two images):</p><table><tr><td> <img
src="http://pdos.csail.mit.edu/~rsc/regexp-img/grep3p.png"><img
src="http://pdos.csail.mit.edu/~rsc/regexp-img/grep4p.png"></td></tr><td><center>Time to match <i>a?<sup>n</sup>a<sup>n</sup></i> against <i>a<sup>n</sup></i></center></td></tr></table><p>So when does this behavior matter?  If you let untrusted users supply regexes, you may have a security issue in your hands, a denial-of-service the very least, if your library is bad.  If you want to be sure your program won&#8217;t run out of memory or out of time, no matter what regex you throw at it, you cannot use the built-in libraries.</p><p>Luckily, there are some <strong>good efficient regex libraries which guarantee linear time matching and fixed memory usage</strong>:</p><ul><li><a
href="http://code.google.com/p/re2/">RE2</a> by Russ Cox, released 2010</li><li><a
href="http://swtch.com/plan9port/unix/">The Plan 9 regex matcher</a> by Rob Pike, late 1980s, early 90s?</li><li><a
href="http://laurikari.net/tre/">TRE</a> by me, released 2001</li></ul><p>Others may exist, but these are in library form.  RE2 is mostly PCRE compatible.  TRE is POSIX compatible, and also supports <a
href="http://hackerboss.com/approximate-regex-matching-in-python/">approximate matching.</a> The Plan 9 matcher has its own API.</p><p>So, there you have it.  Parsing text is one of the things which is best done with a suitable theoretical background. <a
href="http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#1732454">You can&#8217;t parse HTML with regex</a>, and you cannot efficiently parse a regular language with a backtracking matcher.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/approximate-regex-matching-in-python/' rel='bookmark' title='Permanent Link: Approximate Regex Matching in Python'>Approximate Regex Matching in Python</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/is-your-regex-matcher-up-to-snuff/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Metric of the Month: Duplicate Code</title><link>https://hackerboss.com/metric-of-the-month-duplicate-code/</link> <comments>https://hackerboss.com/metric-of-the-month-duplicate-code/#comments</comments> <pubDate>Tue, 09 Feb 2010 21:38:17 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[code]]></category> <category><![CDATA[metrics]]></category> <category><![CDATA[tools]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1613</guid> <description><![CDATA[
There are few hard and fast rules in software development, but this one comes close: don&#8217;t copy and paste code.  Keeping multiple copies around within the same code base is almost never a good idea.
Question is, do you have duplicate code in your code base?  How much would you be willing to bet?
Recently [...]Related posts:<ol><li><a
href='https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/' rel='bookmark' title='Permanent Link: If Your Code Crashes in Production, Does it Make a Sound?'>If Your Code Crashes in Production, Does it Make a Sound?</a></li><li><a
href='https://hackerboss.com/get-rid-of-templates/' rel='bookmark' title='Permanent Link: Get Rid of Source Code Templates'>Get Rid of Source Code Templates</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/metric-of-the-month-duplicate-code/" title="Permanent link to Metric of the Month: Duplicate Code"><img
class="post_image alignnone" src="http://hackerboss.com/pics/do-not-duplicate.jpg" width="482" height="249" alt="Post image for Metric of the Month: Duplicate Code" /></a></p><p><span
class="drop_cap">T</span>here are few hard and fast rules in software development, but this one comes close: don&#8217;t copy and paste code.  Keeping multiple copies around within the same code base is almost never a good idea.</p><p>Question is, do you have duplicate code in <em>your</em> code base?  How much would you be willing to bet?</p><p>Recently I stumbled across a great tool called <a
href="http://www.redhillconsulting.com.au/products/simian/">Simian</a>.  It scans through your code and reports any duplicate lines.  It understands enough programming language syntax so that it can ignore comments, whitespace, curly braces, and variable names.</p><p>Simian hasn&#8217;t been updated for a couple of years now, but it works.  It&#8217;s super easy to point it to your code and have it find duplicates.  I encourage you to try it.  Unfortunately, you may be in for an unpleasant surprise.</p><p><strong>Friends don&#8217;t let friends copy &amp; paste.</strong> That&#8217;s why you&#8217;ll want to set up this tool (or something similar ;) to run nightly against your code base to see if you&#8217;re getting better or worse.  I&#8217;ve built a &#8220;total duplication&#8221; count and a &#8220;top 10 biggest chunks of duplicate code&#8221; reports, updated every night.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/' rel='bookmark' title='Permanent Link: If Your Code Crashes in Production, Does it Make a Sound?'>If Your Code Crashes in Production, Does it Make a Sound?</a></li><li><a
href='https://hackerboss.com/get-rid-of-templates/' rel='bookmark' title='Permanent Link: Get Rid of Source Code Templates'>Get Rid of Source Code Templates</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/metric-of-the-month-duplicate-code/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Should You Be a Generalist Or a Specialist?</title><link>https://hackerboss.com/should-you-be-a-generalist-or-a-specialist/</link> <comments>https://hackerboss.com/should-you-be-a-generalist-or-a-specialist/#comments</comments> <pubDate>Fri, 15 Jan 2010 14:49:33 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Productivity]]></category> <category><![CDATA[career]]></category> <category><![CDATA[generalist]]></category> <category><![CDATA[specialist]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1499</guid> <description><![CDATA[When I was a young student, I had a fashionable infatuation with martial arts.   One day at the dojo I was busy practicing a particular punch to the side of the neck.   The teacher watched my repeated fumbling for a while, and finally pulled me aside and gave me one of the best [...]No related posts.]]></description> <content:encoded><![CDATA[<p></p><p><span
class="drop_cap">W</span>hen I was a young student, I had a fashionable infatuation with martial arts.   One day at the dojo I was busy practicing a particular punch to the side of the neck.   The teacher watched my repeated fumbling for a while, and finally pulled me aside and gave me one of the best lessons I&#8217;ve ever received on how to become a better software developer.</p><h3>Why learning only one thing is hard</h3><p>&#8220;Listen, you won&#8217;t learn the punch right by practicing it in isolation.  You&#8217;re going through the motions but you don&#8217;t know what you&#8217;re doing.  You&#8217;re going to need some context.&#8221;</p><p>OK, I thought, that seems like a good idea.  I&#8217;m not getting anywhere anyway.</p><p>&#8220;Let&#8217;s make the punch a part of a story,&#8221; he said.</p><p>So he taught me a kata.  It incorporated the punch into a sequence of moves against an opponent.  Before learning the kata I did basically know how to execute the punch.  But the kata showed me <em>why</em> I was doing it and that made all the difference.</p><p>My teacher&#8217;s lesson applies to software development as well.  The part you&#8217;re working on is part of a bigger story.  You have to know that story.  It is much easier to do the right things if you teach yourself a little bit about the customers, the business, usability, technology, or anything which is not your specialty but is happening around you anyway.</p><h3>Are you a fake specialist?</h3><p>When you pick a specialty, strive for technical depth.  As <a
href="http://twitter.com/chadfowler">Chad Fowler</a> says in <a
href="http://pragprog.com/titles/cfcar2/the-passionate-programmer">The Passionate Programmer</a>:</p><blockquote><p>Too many of us seem to believe that specializing in something simply means not knowing about other things.</p></blockquote><p>This hits the nail on the head.  If  &#8221;specialist&#8221; does not mean technical depth, then all that is left is an excuse to avoid learning anything else.</p><p>So, here is my advice. Be both.  Be a generalist so you can understand the whole story.  Be a specialist to do your part better than anyone else could.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/should-you-be-a-generalist-or-a-specialist/feed/</wfw:commentRss> <slash:comments>18</slash:comments> </item> <item><title>Building High Performance Software Teams</title><link>https://hackerboss.com/building-high-performance-software-teams/</link> <comments>https://hackerboss.com/building-high-performance-software-teams/#comments</comments> <pubDate>Thu, 24 Dec 2009 07:02:02 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[organization]]></category> <category><![CDATA[Productivity]]></category> <category><![CDATA[teams]]></category> <category><![CDATA[teamwork]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1477</guid> <description><![CDATA[
A matrix organization allows you to build teams with a high degree of specialization and top-notch skills, plan your resourcing easily, and encourages sharing knowledge between product teams.  A matrix organization is great. Except that it&#8217;s not, not for developing software.
It&#8217;s not great when coders don&#8217;t do any testing because it&#8217;s the QA department&#8217;s [...]Related posts:<ol><li><a
href='https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/' rel='bookmark' title='Permanent Link: The Birth of the Grumpy Asshole Programmer'>The Birth of the Grumpy Asshole Programmer</a></li><li><a
href='https://hackerboss.com/recruitment-mistakes/' rel='bookmark' title='Permanent Link: Do You Make These Mistakes When Recruiting Software Developers?'>Do You Make These Mistakes When Recruiting Software Developers?</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/building-high-performance-software-teams/" title="Permanent link to Building High Performance Software Teams"><img
class="post_image alignnone" src="http://hackerboss.com/pics/take-a-number.jpg" width="273" height="440" alt="Post image for Building High Performance Software Teams" /></a></p><p><span
class="drop_cap">A</span> matrix organization allows you to build teams with a high degree of specialization and top-notch skills, plan your resourcing easily, and encourages sharing knowledge between product teams.  A matrix organization is great. Except that it&#8217;s not, not for developing software.</p><p>It&#8217;s not great when coders don&#8217;t do any testing because it&#8217;s the QA department&#8217;s responsibility. It&#8217;s not great when it takes a week to go through the DBA team to have a column added to a database table. It&#8217;s not great when developers have never directly talked to an actual end-user.</p><p>Please take a number.  We will be able to look at your request in three or four days.</p><p>This is why startups get things done quickly.  They have a small number of people, and most of them can and will do <em>everything</em>.  There is no DBA team and no red tape.  You can just add that damn column when you feel like it.</p><p>If you have separate departments for customer support, QA, development, product management, and so on, you should seriously consider tearing down those silos and replace them with real teams.</p><p>Of course, there are limits to what responsibilities teams should have to be successful. You probably shouldn&#8217;t have to set up your own network infrastructure, negotiate the rent, or unblock the toilet.  If you have someone to do these things for you, that&#8217;s great.  If you don&#8217;t&#8230; well, that&#8217;s life.  I would rather unblock a toilet myself than try to keep it in.  You?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/' rel='bookmark' title='Permanent Link: The Birth of the Grumpy Asshole Programmer'>The Birth of the Grumpy Asshole Programmer</a></li><li><a
href='https://hackerboss.com/recruitment-mistakes/' rel='bookmark' title='Permanent Link: Do You Make These Mistakes When Recruiting Software Developers?'>Do You Make These Mistakes When Recruiting Software Developers?</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/building-high-performance-software-teams/feed/</wfw:commentRss> <slash:comments>13</slash:comments> </item> <item><title>The Silver Bullet That Wasn&#8217;t</title><link>https://hackerboss.com/the-silver-bullet-that-wasnt/</link> <comments>https://hackerboss.com/the-silver-bullet-that-wasnt/#comments</comments> <pubDate>Tue, 08 Dec 2009 19:45:54 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[IT]]></category> <category><![CDATA[google]]></category> <category><![CDATA[indexing]]></category> <category><![CDATA[intranet]]></category> <category><![CDATA[SEO]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1443</guid> <description><![CDATA[
I have a confession to make.  I occasionally fall prey to a most basic mistake: I think a tool will solve a problem before I even understand the problem.  Here&#8217;s what happened this time&#8230;
Like any company, we have an intranet.  Ours is a motley collection of internal websites and tools: we have a [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/the-silver-bullet-that-wasnt/" title="Permanent link to The Silver Bullet That Wasn&#8217;t"><img
class="post_image alignnone" src="http://hackerboss.com/pics/hammer-screw.jpg" width="383" height="313" alt="Post image for The Silver Bullet That Wasn&#8217;t" /></a></p><p><span
class="drop_cap">I</span> have a confession to make.  I occasionally fall prey to a most basic mistake: I think a tool will solve a problem before I even understand the problem.  Here&#8217;s what happened this time&#8230;</p><p>Like any company, we have an intranet.  Ours is a motley collection of internal websites and tools: we have a wiki, a bug tracker, documents on file shares, and a number of other services of varying importance.  Finding information is hard if you don&#8217;t know where to look.  So I figured the best way to solve the problem is a Google Mini.</p><p><img
class="alignleft" src="http://hackerboss.com/pics/google-mini.jpg" alt="" width="360" height="169" />A Google Mini is your own private google rolled into a single rack unit.  It crawls your network, indexes your content (including PDF and various Microsoft formats), and comes with the familiar google search interface.  It sounded like the perfect thing to solve our little problem.</p><p>So I ordered one.  The device arrived less than 24 hours after the order which was impressive given that it was shipped from the UK to Finland.  Setting it up was easy and everything worked as advertised.</p><p>The obvious next step was to let the bot loose to crawl our network.  I could hardly wait to get all the information in our intranet at my fingertips.  What could go wrong?</p><h3>Lesson 1: Some services choke when crawled.</h3><p>It hadn&#8217;t occurred to me that our internal web servers had never been crawled before.  Oops.</p><p>Some pages would take several seconds of CPU time to generate and googlebot was pinning the CPU to 100% on these servers.</p><p>Some servers generated never-ending lists of URLs, so googlebot was constantly finding &#8220;new&#8221; pages.  It quickly went over the limit of number of documents supported by the device.</p><p>Most of these problems were solved by blacklisting certain URL patterns in the Google Mini configuration.  Also, instead of a &#8220;crawl everything&#8221; approach, I switched to a &#8220;crawl only selected servers&#8221; approach.</p><h3>Lesson 2: Some services cannot be crawled at all.</h3><p>Most of our internal web services are not designed to be crawled at all. They may require logging in, for example, and Google Mini may have trouble handling that. None had a proper robots.txt and sitemap.  I&#8217;m still working on getting some of that stuff indexed at all.</p><h3>Lesson 3: Indexing bad content won&#8217;t improve anything.</h3><p>It&#8217;s like shining a bright light on a big pile of crap.  It&#8217;s still a pile of crap, but you can see it more clearly.</p><p>Our intranet is hardly built using good SEO practices, so it&#8217;s natural that googlebot has trouble figuring out what pages and keywords are important.  But mostly the problem is just an abundance of obsolete and outdated content.  The solution will be to to get rid of most of it.</p><p>Don&#8217;t get me wrong: our  Google Mini works very well, it&#8217;s already been quite useful, and I&#8217;m quite happy with it.  I can actually find stuff from our wiki now.  But it won&#8217;t turn a collection of obsolete Word documents from &#8216;02 into useful content.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-silver-bullet-that-wasnt/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>If Your Code Crashes in Production, Does it Make a Sound?</title><link>https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/</link> <comments>https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/#comments</comments> <pubDate>Wed, 18 Nov 2009 20:47:33 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Product Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[crash]]></category> <category><![CDATA[metrics]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[quality]]></category> <category><![CDATA[WER]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1390</guid> <description><![CDATA[
Meet Frank.  Frank works as a product manager at Faxes-R-Us. He&#8217;s finishing up a presentation on their latest fax machine model: FRU-1221i with integrated Twitter and Facebook support.  This one will sell like hot cakes.
Frank&#8217;s presentation is due tomorrow, and he&#8217;s now trying to include pictures on some of the slides.  [...]Related posts:<ol><li><a
href='https://hackerboss.com/platforms-come-with-a-culture/' rel='bookmark' title='Permanent Link: Platforms Come With a Culture'>Platforms Come With a Culture</a></li><li><a
href='https://hackerboss.com/metric-of-the-month-duplicate-code/' rel='bookmark' title='Permanent Link: Metric of the Month: Duplicate Code'>Metric of the Month: Duplicate Code</a></li><li><a
href='https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/' rel='bookmark' title='Permanent Link: The Birth of the Grumpy Asshole Programmer'>The Birth of the Grumpy Asshole Programmer</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/" title="Permanent link to If Your Code Crashes in Production, Does it Make a Sound?"><img
class="post_image alignnone" src="http://hackerboss.com/pics/crashed.jpg" width="422" height="284" alt="Post image for If Your Code Crashes in Production, Does it Make a Sound?" /></a></p><p><span
class="drop_cap">M</span>eet Frank.  Frank works as a product manager at Faxes-R-Us. He&#8217;s finishing up a presentation on their latest fax machine model: FRU-1221i with integrated Twitter and Facebook support.  This one will sell like hot cakes.</p><p>Frank&#8217;s presentation is due tomorrow, and he&#8217;s now trying to include pictures on some of the slides.  At Faxes-R-Us, they have a company policy to build all presentations using SlidePointX.  This is where you come in: SlidePointX is your product.  As Frank drags a picture of the FRU-1221i into SlidePointX, the program promptly crashes.  No worries, mutters Frank and tries again.  Another crash.  Again.  Crash.  Again.  Crash.  Frank starts to panic.  Again.  It worked!  Phew.</p><p>What do you think will be Frank&#8217;s next step?  Will he reproduce the bug, maybe inspect some crash dumps, and write a nice detailed bug report and send it to you?  No, I didn&#8217;t think so either.  All Frank wanted is to finish his presentation, so that&#8217;s what he&#8217;s going to concentrate on. <strong>Your product just crashed four times in production use, and you will never hear about it.</strong></p><p>Enter automatic error reporting.</p><p>Automatic error reporting, a.k.a. <a
href="http://en.wikipedia.org/wiki/Crash_Reporter">crash reporting</a> is an application or technology which captures software crash data and sends it to you &#8211; at the user&#8217;s consent, of course. The particulars vary between different solutions, but typically you get access to crash dumps or at least stack traces.</p><p>Automatic error reports are invariably much more detailed than anything a normal user could ever give you. There are few things in life more frustrating than trying to reproduce a bug based on inadequate information. <strong>A full crash dump is pure bliss compared to &#8220;crashes when dragging pictures, please fix&#8221;.</strong></p><p>But that&#8217;s not where the real power of automatic error reporting lies.  Here&#8217;s what Microsoft has to say about <a
href="http://www.microsoft.com/whdc/winlogo/maintain/StartWER.mspx">Windows Error Reporting (WER)</a>:</p><blockquote><p> Broad-based trend analysis of error reporting data shows that across all the issues that exist on the affected Windows platforms and the number of incidents received:</p><ul><li>Fixing 20 percent of the top-reported bugs can solve 80 percent of customer issues.</li><li>Addressing 1 percent of the bugs would address 50 percent of the customer issues.</li></ul></blockquote><p>Let me repeat that last part in case you missed it: <strong>Addressing 1 percent of the bugs would address 50 percent of the customer issues.</strong> You can&#8217;t do that if you don&#8217;t know what the top bugs are.  Automatic error reporting provides you with invaluable intelligence of the stability of your product across different versions and over time.</p><p>WER is built into Windows. <strong>If you ship applications on Windows, you need to start looking at your WER reports.</strong> I insist.  To get going, the only cost for you is to get a code-signing certificate from VeriSign and you&#8217;re all set for WER.  Don&#8217;t just sit there, go <a
href="https://winqual.microsoft.com/Help/Default.htm#obtaining_a_verisign_class_3_digital_id.htm">do it now</a>!</p><p>On other platforms (Mac, Linux, commercial Unix), the sad state of affairs seems to be that there are typically no built-in tools that software vendors can use.  If you want automatic error reports, you may have to implement it yourself. <strong>If you know about non-Windows solutions in this area, please let me know in the comments.</strong></p><p>One of your goals should obviously be that there are no crashes in the field.  But just in case there are problems, wouldn&#8217;t you like to see the full gory details?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/platforms-come-with-a-culture/' rel='bookmark' title='Permanent Link: Platforms Come With a Culture'>Platforms Come With a Culture</a></li><li><a
href='https://hackerboss.com/metric-of-the-month-duplicate-code/' rel='bookmark' title='Permanent Link: Metric of the Month: Duplicate Code'>Metric of the Month: Duplicate Code</a></li><li><a
href='https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/' rel='bookmark' title='Permanent Link: The Birth of the Grumpy Asshole Programmer'>The Birth of the Grumpy Asshole Programmer</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/if-your-code-crashes-in-production-does-it-make-a-sound/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>The Three Doors of Type Systems</title><link>https://hackerboss.com/the-three-doors-of-type-systems/</link> <comments>https://hackerboss.com/the-three-doors-of-type-systems/#comments</comments> <pubDate>Wed, 11 Nov 2009 09:00:23 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[dynamic typing]]></category> <category><![CDATA[go]]></category> <category><![CDATA[languages]]></category> <category><![CDATA[static typing]]></category> <category><![CDATA[type inference]]></category> <category><![CDATA[type systems]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1349</guid> <description><![CDATA[
Every so often, I get drawn into a discussion about the merits of static typing (Java, C, C#, ML) versus dynamic typing (JavaScript, Python, Ruby, Scheme).  Many programmers seem to be firmly in one camp or the other.  But somewhere in between, there&#8217;s a third door.  Let me explain&#8230;
I hate dynamic typing.
Dynamic [...]Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/the-three-doors-of-type-systems/" title="Permanent link to The Three Doors of Type Systems"><img
class="post_image alignnone" src="http://hackerboss.com/pics/false-choice.jpg" width="425" height="282" alt="Post image for The Three Doors of Type Systems" /></a></p><p><span
class="drop_cap">E</span>very so often, I get drawn into a discussion about the merits of static typing (Java, C, C#, ML) versus dynamic typing (JavaScript, Python, Ruby, Scheme).  Many programmers seem to be firmly in one camp or the other.  But somewhere in between, there&#8217;s a third door.  Let me explain&#8230;</p><p>I hate dynamic typing.</p><p>Dynamic typing leaves too much room to leave mistakes in your code. Stupid ones, too, the kind where you try to subtract apples from golf clubs.  And the kinds where you sort of forgot to implement the &#8220;else&#8221; part.</p><p>These are typical mistakes which could be proved, by the compiler, to never possibly work.  Only it&#8217;s not even trying, and it&#8217;s leaving it all up to me, a dodgy forgetful emotional interrupted tired inferior human, to stare at it long enough to assure myself that it will work correctly in all possible situations.  It won&#8217;t, of course.</p><p>I hate static typing.</p><p>Static typing makes you think about types when you want to think about your program.  Before you can run anything, the compiler insists that everything is <i>perfect</i>, but you&#8217;re only just starting to build the shape of your code.  You probably don&#8217;t know what it&#8217;s going to look like when it&#8217;s finished.  Perfect is for later.</p><p>I hate lack of type inference.</p><p>Spelling out the types for each variable and parameter and return type and field makes your programs ugly.  Most of that type information is implicitly clear to you, so it makes no sense that you have to always explicitly mention every type in the actual code.  The compiler and IDE should do some of that for you.</p><p>I hate type inference.</p><p>Full-blown type inference makes type errors insanely difficult to locate.  The compiler figures out that the types in your code aren&#8217;t adding up, but it has no idea where the error actually is.  The problem is that often you have no idea, either.</p><p>The point I want to make is that <strong>the choice between dynamic and static typing is a false dichotomy.</strong> You don&#8217;t need to choose between showering and brushing your teeth.  You do both.  In the same way, you shouldn&#8217;t have to choose between static typing or dynamic typing.  You should be able to use the appropriate tools in the appropriate places at the appropriate time.  The right kind of static typing is <strong>discretionary static typing</strong>.</p><p>Luckily, programming languages are already moving in this direction.  Yesterday, Google published <a
href="http://golang.org">a new programming language called Go</a>:</p><blockquote><p> Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language</p></blockquote><p>That sounds like just what the doctor ordered.  C# from Microsoft is also steadily gaining some type inference and dynamic typing features.  Both C# and Go are actively trying to fix some of the biggest pain points in the working programmers&#8217; lives.</p><p>I for one will be taking a good look of what&#8217;s behind the third door.  Will you?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-three-doors-of-type-systems/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Hashed Bits becomes Hacker Boss</title><link>https://hackerboss.com/hashed-bits-becomes-hacker-boss/</link> <comments>https://hackerboss.com/hashed-bits-becomes-hacker-boss/#comments</comments> <pubDate>Mon, 09 Nov 2009 07:33:30 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Meta]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1342</guid> <description><![CDATA[I decided to change the name of this blog to something more descriptive and less &#8220;meh&#8221;.   This blog is about developing software and managing development teams.  That is, about hacking, and about being a boss.  Frequently at the same time.
It is likely that RSS subscribers will see old posts coming up [...]No related posts.]]></description> <content:encoded><![CDATA[<p></p><p>I decided to change the name of this blog to something more descriptive and less &#8220;meh&#8221;.   This blog is about developing software and managing development teams.  That is, about hacking, and about being a boss.  Frequently at the same time.</p><p>It is likely that RSS subscribers will see old posts coming up as new.  I apologize for the inconvenience.</p><p>And now, back to our regular program.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/hashed-bits-becomes-hacker-boss/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>The Essence of Lambda</title><link>https://hackerboss.com/the-essence-of-lambda/</link> <comments>https://hackerboss.com/the-essence-of-lambda/#comments</comments> <pubDate>Fri, 06 Nov 2009 20:59:27 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[lambda]]></category> <category><![CDATA[scheme]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1287</guid> <description><![CDATA[
When I was studying Scheme on a programming course at HUT, I remember I was a bit baffled by first-class functions.  My previous experiences were with C, Pascal, Basic, and other languges which didn&#8217;t have first-class functions.  Data is data, code is code.  You don&#8217;t go mixing those two.  Why would [...]Related posts:<ol><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li><li><a
href='https://hackerboss.com/the-three-doors-of-type-systems/' rel='bookmark' title='Permanent Link: The Three Doors of Type Systems'>The Three Doors of Type Systems</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/the-essence-of-lambda/" title="Permanent link to The Essence of Lambda"><img
class="post_image alignnone" src="http://hackerboss.com/pics/lambda.jpg" width="425" height="282" alt="Post image for The Essence of Lambda" /></a></p><p><span
class="drop_cap">W</span>hen I was studying Scheme on a programming course at <a
href="http://www.hut.fi/en/">HUT</a>, I remember I was a bit baffled by first-class functions.  My previous experiences were with C, Pascal, Basic, and other languges which didn&#8217;t have first-class functions.  Data is data, code is code.  You don&#8217;t go mixing those two.  Why would you want to create new functions on the fly and pass them around as values?  Crazy talk!</p><p>What really made me understand was the following homework exercise:</p><blockquote><p> Define cons, car, and cdr without using any built-in data structures.  Hint: Use first-class functions.</p></blockquote><p>As you may know, cons is a function which takes two arguments and returns a single value which contains the two argument values inside. This single value is called a pair (or sometimes a cons cell). The car and cdr functions extract the left and right parts of a pair, respectively.</p><p>Without further ado, here&#8217;s the solution.  I suppose most readers aren&#8217;t necessarily familiar with Scheme, so I&#8217;m including both JavaScript and Scheme code.</p><table
class="archivetbl"><tr><td><div
class="wp_syntax"><div
class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> cons<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> a
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> b
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> cdr<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></div></div></td><td><div
class="wp_syntax"><div
class="code"><pre class="scheme">&nbsp;</pre></div></div></td></tr></table><p>This really helped my understand what this lambda business is all about.  It&#8217;s more than a function without a name.  It&#8217;s less magical than generating code on the fly, which was what I first believed must be happening.  A first-class function is a way to bind together some values (a and b) together with some code operating on those values (the if).  The result is a function you can call like a regular function.</p><p>Sometimes, I&#8217;m a bottom-up kind of guy, so the final missing piece of understanding had to come from figuring out how lambda could be implemented by the compiler or interpreter.  Here&#8217;s how:</p><table
class="archivetbl"><tr><td><div
class="wp_syntax"><div
class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> cons_f<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> a
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> b
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> cons<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span>cons_f<span style="color: #339933;">,</span> a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> cdr<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> p<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></div></div></td></tr></table><p>So when the compiler encounters a function body which refers to variables outside the body, it kind of lifts the lambda into a top-level function.  Any open variables are made into new explicit parameters for the function.  The function value is basically a vector with a reference to this &#8220;normal&#8221; function, plus the values of the open variables at the time.</p><p>Technically this is not exactly how things happen, but hopefully you get the point.  The point being that <strong>deep down, lambda is really not that much more special than allocating a vector</strong>.</p><p>As for the solution itself, we can actually do a bit better. We don&#8217;t really need to use a conditional:</p><table
class="archivetbl"><tr><td><div
class="wp_syntax"><div
class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> cons<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> f<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> a <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> cdr<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> b <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></div></div></td><td><div
class="wp_syntax"><div
class="code"><pre class="scheme">&nbsp;</pre></div></div></td></tr></table><p>We can go even more basic than this.  The above code uses functions with two arguments.  Let&#8217;s make it <a
href="http://en.wikipedia.org/wiki/Currying"><i>curried</i></a>, and only use functions with one argument.  It&#8217;ll change the API, though, so instead of <code>cons(a, b)</code> you call <code>cons(a)(b)</code>.</p><table
class="archivetbl"><tr><td><div
class="wp_syntax"><div
class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> cons <span style="color: #339933;">=</span>
  <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> f<span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> 
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> car<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> a <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> cdr<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> p<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> b
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></div></div></td><td><div
class="wp_syntax"><div
class="code"><pre class="scheme">&nbsp;</pre></div></div></td></tr></table><p>This is arguably as basic as it gets.  We&#8217;ve defined cons, car, and cdr using nothing but function definitions and function calls.</p><p>Hopefully this little exercise helped you as much as it helped me.  They say you don&#8217;t really know a programming language until you&#8217;ve learned to hate it with a passion.  I&#8217;d say <strong>you don&#8217;t really know a programming language until you&#8217;ve implemented a compiler for it.</strong></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li><li><a
href='https://hackerboss.com/the-three-doors-of-type-systems/' rel='bookmark' title='Permanent Link: The Three Doors of Type Systems'>The Three Doors of Type Systems</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-essence-of-lambda/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>A Developer&#8217;s Most Important Interface</title><link>https://hackerboss.com/a-developers-most-important-interface/</link> <comments>https://hackerboss.com/a-developers-most-important-interface/#comments</comments> <pubDate>Sun, 01 Nov 2009 17:45:00 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[IT]]></category> <category><![CDATA[hardware]]></category> <category><![CDATA[keyboards]]></category> <category><![CDATA[typing]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1252</guid> <description><![CDATA[
A long time ago, I was actively playing a MUD.  A MUD is like World of Warcraft, only on a much smaller scale, and there are no graphics.  It&#8217;s all text based. To make your character do anything, you have to type commands at the prompt.
The thing with this MUD was that fights [...]Related posts:<ol><li><a
href='https://hackerboss.com/how-i-learned-to-type/' rel='bookmark' title='Permanent Link: A Little Known Way to Learn Touch Typing'>A Little Known Way to Learn Touch Typing</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/a-developers-most-important-interface/" title="Permanent link to A Developer&#8217;s Most Important Interface"><img
class="post_image alignnone" src="http://hackerboss.com/pics/keyboard-love.jpg" width="283" height="424" alt="Post image for A Developer&#8217;s Most Important Interface" /></a></p><p><span
class="drop_cap">A</span> long time ago, I was actively playing a MUD.  A MUD is like World of Warcraft, only on a much smaller scale, and there are no graphics.  It&#8217;s all text based. To make your character do anything, you have to type commands at the prompt.</p><p>The thing with this MUD was that fights were not strictly turn based.  If you were too slow to cast your next spell, your wizard would be standing there with a vacant look in his eyes while some troll is bashing him to bits with a morning star.  The faster you type, the faster you cast the next spell.</p><p>After a few hundred hours of playing, typing no longer exists as a separate activity.  It&#8217;s automatic. You think &#8220;fireball&#8221; and the words appear on screen. Technically, your fingers are still pressing keys, but for all practical purposes your mind is now directly linked with the game.</p><p><img
class="alignright" src="http://hackerboss.com/pics/matrix-sockets.jpg" alt="" width="309" height="210" /><br
/> The same kind of mind-to-machine link forms after enough practice with your programming language and IDE, or <a
href="http://hackerboss.com/the-shell-is-like-a-dish-washer/">shell</a>. You don&#8217;t need a sci-fi socket on the back of the skull for that.  All you need is enough practice.</p><p>You also need a good keyboard.</p><p>A good keyboard is one which you forget is there.  A good keyboard doesn&#8217;t jam the Enter key when you press it on the upper right corner.  A good keyboard has zero packet loss from your brain to the computer.</p><p>My new favorite keyboard is the Apple aluminium keyboard. The tactile feedback is just right. It&#8217;s small, so there&#8217;s more room for other stuff on my desk.  It&#8217;s thin, so I don&#8217;t need a separate wrist rest at all. It looks beautiful, and is obviously the result of a great deal of design work. This keyboard even <em>sounds</em> good.</p><p><a
href="http://www.apple.com/keyboard/"><img
class="alignnone" src="http://hackerboss.com/pics/apple-keyboard.jpg" alt="" width="490" height="229" /></a></p><p>I would be very interested to hear what you have to say about keyboards. What is your favorite keyboard?  Give your opinion in <a
href="http://hackerboss.com/a-developers-most-important-interface/#comments">the comments section</a>!</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/how-i-learned-to-type/' rel='bookmark' title='Permanent Link: A Little Known Way to Learn Touch Typing'>A Little Known Way to Learn Touch Typing</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/a-developers-most-important-interface/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>Do You Speak Binary?</title><link>https://hackerboss.com/do-you-speak-binary/</link> <comments>https://hackerboss.com/do-you-speak-binary/#comments</comments> <pubDate>Tue, 20 Oct 2009 08:29:39 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[binary]]></category> <category><![CDATA[hiring]]></category> <category><![CDATA[puzzles]]></category> <category><![CDATA[skills]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1225</guid> <description><![CDATA[How well do you know the fundamental unit of information, communication, computation?
When interviewing coders, I often like to ask them to explain how they would implement a function which counts the number of bits set in an integer.  This is often called the &#8220;population counting&#8221; problem.  In Beautiful Code: Leading Programmers Explain How [...]No related posts.]]></description> <content:encoded><![CDATA[<p></p><p><span
class="drop_cap">H</span>ow well do you know the fundamental unit of information, communication, computation?</p><p>When interviewing coders, I often like to ask them to explain how they would implement a function which counts the number of bits set in an integer.  This is often called the &#8220;population counting&#8221; problem.  In <a
href="http://www.amazon.com/dp/0596510047?tag=hashedbits-20">Beautiful Code: Leading Programmers Explain How They Think</a>, Henry S. Warren, Jr. gives a wonderful treatment of the population count problem.  This C code implements a clever algorithm to compute number of set bits in one 32-bit word:</p><div
class="wp_syntax"><div
class="code"><pre class="c"><span style="color: #808080; font-style: italic;">/* Counts 1-bits in a word. */</span>
<span style="color: #993333;">int</span> pop<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  x <span style="color: #339933;">=</span> x <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x55555555</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x33333333</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x33333333</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x0F0F0F0F</span><span style="color: #339933;">;</span>
  x <span style="color: #339933;">=</span> x <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  x <span style="color: #339933;">=</span> x <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> x <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x0000003F</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Can you figure out how it works?</p><p>For a really hard-core puzzle, try to figure out this piece of code from the Quake code.  It computes the inverse square root of a floating point number:</p><div
class="wp_syntax"><div
class="code"><pre class="c"><span style="color: #993333;">float</span> InvSqrt<span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span> x<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
   <span style="color: #993333;">float</span> xhalf <span style="color: #339933;">=</span> <span style="color:#800080;">0.5f</span> <span style="color: #339933;">*</span> x<span style="color: #339933;">;</span>
   <span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>x<span style="color: #339933;">;</span>
   i <span style="color: #339933;">=</span> <span style="color: #208080;">0x5f3759d5</span> <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   x <span style="color: #339933;">=</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">float</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>i<span style="color: #339933;">;</span>
   x <span style="color: #339933;">=</span> x<span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color:#800080;">1.5f</span> <span style="color: #339933;">-</span> xhalf<span style="color: #339933;">*</span>x<span style="color: #339933;">*</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Wow.  If you need to cheat (I did), the <a
href="http://www.google.com/search?q=quake+invsqrt">web is full of explanations</a>.  The one that really helped me understand was <a
href="http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/">by Kalid Azad at BetterExplained</a>.</p><p><strong>I firmly believe that every programmer should try to build a good working understanding of the bit world</strong>.  It&#8217;s not that you have to know that stuff to be able to write (most) programs.  But look at it this way.  That computer on your desk has a CPU in it.  That CPU is executing billions of instructions per second to execute your code.  Are you really not interested at all on what&#8217;s going on in there?  Don&#8217;t you want to know <a
href="http://www.codinghorror.com/blog/archives/001266.html">why computers suck at math?</a></p><p><strike>If the next coder you interview has trouble answering more than a couple of the following, that should be a no hire:</strike><br
/> The next time you are interviewing a coder, here are some questions you could ask to probe their understanding of the binary system:</p><ul><li>What are the first ten powers of two?</li><li>What is 0&#215;7F in binary? In decimal?</li><li>What does two&#8217;s complement mean?</li><li>How would you extract the 8 low-order bits from a word?</li><li>How would you count the number of bits in a word?</li><li>What arithmetic operation does shifting right by one bit correspond to?</li></ul><p>To me, <strong>total lack of understanding in this area is a big red flag</strong> and should cause a no hire.  It means that you either haven&#8217;t been programming long enough to encounter these bit-level problems, or worse, you did encounter them but gave up for one reason or another.  It&#8217;s a real confidence booster to know that you can, if need be, go all the way down to the bit level to solve a problem or understand a bug.</p><p>It&#8217;s all ones and zeroes, right?  The bits are your friends.  How well do you know them?</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/do-you-speak-binary/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>5 Favorite Excuses to Avoid Fixing Your Architecture</title><link>https://hackerboss.com/5-favorite-techniques-to-avoid-fixing-your-architecture/</link> <comments>https://hackerboss.com/5-favorite-techniques-to-avoid-fixing-your-architecture/#comments</comments> <pubDate>Mon, 12 Oct 2009 20:05:20 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Software Development]]></category> <category><![CDATA[architecture]]></category> <category><![CDATA[fallacies]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1191</guid> <description><![CDATA[
Do you remember your last quarrel over whether the current architecture of your software is a good one?  Were you defending or attacking?
I&#8217;m sure some parts of that discussion weren&#8217;t completely rational.  Here&#8217;s a list of some of my favorite irrational arguments against fixing a broken architecture.  Maybe the list helps you [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/5-favorite-techniques-to-avoid-fixing-your-architecture/" title="Permanent link to 5 Favorite Excuses to Avoid Fixing Your Architecture"><img
class="post_image alignnone" src="http://hackerboss.com/pics/denial.jpg" width="424" height="283" alt="Post image for 5 Favorite Excuses to Avoid Fixing Your Architecture" /></a></p><p><span
class="drop_cap">D</span>o you remember your last quarrel over whether the current architecture of your software is a good one?  Were you defending or attacking?</p><p>I&#8217;m sure some parts of that discussion weren&#8217;t completely rational.  Here&#8217;s a list of some of my favorite irrational arguments against fixing a broken architecture.  Maybe the list helps you recognize them as irrational the next time you hear them or use them yourself.</p><h3>1. It&#8217;ll be fine after these fixes</h3><p>This one is popular among people who have never really written a lot of code, at least not of the high quality kind.  They view software quality as something than can be added later. <strong>They think quality is something which can be poured in later, in controlled doses, carefully avoiding adding too much</strong> to avoid spending too much time on quality which is above the market expectation.</p><p><strong>High software quality has to be built in right from the start.</strong> You can&#8217;t pour it in afterwards.  If the design is poor, no amount of bug fixing will get you to rock solid.  If you keep fixing it long enough, you might get to &#8220;works most of the time&#8221;, but you will never reach rock solid.</p><h3>2. There is no problem</h3><p>Flat-out denying that there is any problem is a powerful trick.<strong> Deny all evidence. </strong> If there is evidence, place the blame on third parties, the operating system, the users, whatever.   If you have to, shoot the messenger.</p><p>The tendency to employ this technique seems to be stronger in people who have spent considerable amounts of time designing and creating the broken architecture.  You probably define yourself through the work you have done, at least to some extent.  What was the last thing you created which you are proud of? <strong> How hard would it be to admit that your creation is, in fact, a load of crap? </strong> I bet it would be easier for you to find fault somewhere else, or simply deny that there is anything wrong in the first place.</p><h3>3. Developers always want to rewrite everything anyway</h3><p>The power of this technique lies in the fact that there is a grain of truth in it. <strong>Many developers have this built-in tendency to build new stuff instead of patching up the old stuff.</strong> For me, I think it has something to do with <a
href="http://hackerboss.com/the-programming-high/">how I was introduced to programming</a>.  I fell in love with creating new impressive things, and that&#8217;s what I want to do again and again.</p><p><strong>However, that grain of truth is not a logical argument against fixing your architecture.</strong> If you know that the smelly guy down the hall always eats at Burger King and never at McDonalds,  you still have no information about which is the better choice for lunch.  All you know is that the smelly guy likes his whoppers.</p><h3>4. It was built by our best engineers</h3><p>The architecture was designed by your very best engineers, so it cannot possibly be a bad architecture, right?  Besides, those engineers are too important to risk making them mad.  If we can&#8217;t trust our best engineers, who can we trust?</p><p><strong>S</strong><strong>mart people do stupid things all the time.</strong> It&#8217;s often impossible to know beforehand how something turns out to work in real life.  The smart thing to do is to adjust, refactor, redesign, and rewrite as necessary.  It&#8217;s not very smart to keep going with the first thing that kinda worked.</p><h3>5. This architecture will give us benefits in the future</h3><p>This technique works best if you are vague.  Things such as scalability and flexibility sound good, as do promises about how the architecture can be leveraged in the future to rapidly build new and innovative applications.  Being very specific and concrete will probably reveal that the architecture is not, in fact, superior to the alternatives.</p><p>So, that was my list of favorite techniques to bury your head in the sand.   When was the last time you used them yourself?  What would you add to the list?</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/5-favorite-techniques-to-avoid-fixing-your-architecture/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Platforms Come With a Culture</title><link>https://hackerboss.com/platforms-come-with-a-culture/</link> <comments>https://hackerboss.com/platforms-come-with-a-culture/#comments</comments> <pubDate>Tue, 06 Oct 2009 19:56:05 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Product Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[platforms]]></category> <category><![CDATA[porting]]></category> <category><![CDATA[sql]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1159</guid> <description><![CDATA[
Porting software to another platform is tricky business.  Take the first version of Safari for Windows as an example.  It was not a great success, because Safari 3 on Windows did not quite fit in:
Other grumbles were more because Safari seems like a Mac-application, making it seem out of place on a Windows [...]Related posts:<ol><li><a
href='https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/' rel='bookmark' title='Permanent Link: 6 Tips for Small Software Vendors to Understand Enterprise Customers'>6 Tips for Small Software Vendors to Understand Enterprise Customers</a></li><li><a
href='https://hackerboss.com/how-to-distribute-commercial-python-applications/' rel='bookmark' title='Permanent Link: How to Distribute Commercial Python Applications'>How to Distribute Commercial Python Applications</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/platforms-come-with-a-culture/" title="Permanent link to Platforms Come With a Culture"><img
class="post_image alignnone" src="http://hackerboss.com/pics/mismatch.jpg" width="425" height="282" alt="Post image for Platforms Come With a Culture" /></a></p><p><span
class="drop_cap">P</span>orting software to another platform is tricky business.  Take the first version of Safari for Windows as an example.  It was not a great success, because Safari 3 on Windows <a
href="http://lowendmac.com/mac2win/07/0619.html">did not quite fit in</a>:</p><blockquote><p>Other grumbles were more because Safari seems like a Mac-application, making it seem out of place on a Windows desktop.</p><p>Mac-users, firmly convinced of the superiority of the Mac platform may assume that a Mac-app running on Windows should &#8220;obviously&#8221; appear superior to Windows users. That&#8217;s not the case.</p></blockquote><p>Even if you were to accept that the font rendering in Safari 3 is superior to Windows standard font rendering, the <strong>difference sticks out like a sore thumb</strong>.  In Safari 4 for Windows <a
href="http://www.appletell.com/apple/comment/safari-4-beta-for-windows-first-impressions/">Apple fixed most of the issues</a>:</p><blockquote><p>Safari now looks more like a standard Windows app.  Previous versions stuck with the iTunes/OS X brushed metal interface, which stood out for several reasons: the buttons and scroll bars were standard OS X Aqua elements, rather than standard Windows items.</p></blockquote><p>So, when porting to a new operating system simply getting it to run is nowhere near enough. <strong>Operating systems come with a culture</strong>, complete with their own installers, GUI style, jargon, and soft drink preferences. <strong>Your port has to match the culture</strong>.</p><p>Sometimes you need to port between platforms which aren&#8217;t operating systems. You might feel the need to support two or more different RDBMS&#8217;s, for example. SQL is a standard, right?  What could go wrong?   Jim Melton, the editor of the SQL standard for 20 years, said in <a
href="http://www.se-radio.net/podcast/2009-06/episode-137-sql-jim-melton">SE Radio Episode 137: SQL with Jim Melton</a>:</p><blockquote><p>&#8220;It&#8217;s unclear exactly what the driving factors were for most of the organizations [for standardizing SQL].  I know for some of the vendors who eventually became dominant, ones like Oracle, IBM, and Sybase, the driving motivation was the ability to have the <em>illusion</em> of portability.  Yes, I&#8217;m being honest here &#8211; so that you could sell your system to a customer and allow him to believe that there was some chance he would be able to port his programs, and that there wouldn&#8217;t be vendor lock-in.</p></blockquote><p>Not all standards were born alike, huh?</p><p>So, all this is evidence that you shouldn&#8217;t take porting lightly.  It&#8217;s easy to underestimate the cost or downplay the importance of porting the culture.  And the technical side ain&#8217;t always a walk in the park, either.</p><p>After the initial port, you&#8217;ll need to develop, test, support, and maintain the software on two platforms instead of just the one. <strong>Introducing a second platform can effectively double the surface area for bugs to attach to.</strong> Also, once you&#8217;ve opened that door, why not add a third platform?  A fourth? <strong>Are you sure it&#8217;s going to be worth it?</strong></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/' rel='bookmark' title='Permanent Link: 6 Tips for Small Software Vendors to Understand Enterprise Customers'>6 Tips for Small Software Vendors to Understand Enterprise Customers</a></li><li><a
href='https://hackerboss.com/how-to-distribute-commercial-python-applications/' rel='bookmark' title='Permanent Link: How to Distribute Commercial Python Applications'>How to Distribute Commercial Python Applications</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/platforms-come-with-a-culture/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Thinking Forth: the Unsung Classic</title><link>https://hackerboss.com/thinking-forth-the-unsung-classic/</link> <comments>https://hackerboss.com/thinking-forth-the-unsung-classic/#comments</comments> <pubDate>Fri, 02 Oct 2009 20:27:36 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Book reviews]]></category> <category><![CDATA[Productivity]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[books]]></category> <category><![CDATA[forth]]></category> <category><![CDATA[self-help]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1139</guid> <description><![CDATA[
A colleague recently pointed me to the book Thinking Forth by Leo Brodie.
While it is heavily a book about Forth (the programming language), it&#8217;s even more a book about programming and problem solving in general. I don&#8217;t know Forth, and have no intention of learning it, but I found this book to be chock full [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/thinking-forth-the-unsung-classic/" title="Permanent link to Thinking Forth: the Unsung Classic"><img
class="post_image alignleft" src="http://thinking-forth.sourceforge.net/cover.jpg" width="158" height="238" alt="Post image for Thinking Forth: the Unsung Classic" /></a></p><p><span
class="drop_cap">A</span> colleague recently pointed me to the book Thinking Forth by Leo Brodie.</p><p>While it is heavily a book about Forth (the programming language), it&#8217;s even more a book about programming and problem solving in general. I don&#8217;t know Forth, and have no intention of learning it, but I found this book to be chock full of insight and humor which apply today just as well as they did when Thinking Forth was first published.</p><p>Among the fun parts are gems like this:</p><p><img
class="alignnone" src="http://hackerboss.com/pics/universal-processor.jpg" alt="" width="399" height="516" /></p><p>Among the pearls of wisdom, of which there are many, you can find this:</p><blockquote><p>&#8220;You don&#8217;t understand a problem until you can simplify it.&#8221;</p></blockquote><p>And this:</p><blockquote><p>&#8220;Start simple. Get it running. Learn what you’re trying to do. Add complexity gradually, as needed to fit the requirements and constraints. Don’t be afraid to restart from scratch.&#8221;</p></blockquote><p>Today, this would probably be called some sort of an agile method.  I&#8217;m kind of thinking it&#8217;s just common sense.</p><p>Especially the first half of the book concentrates on universal concepts like analysis and planning, conceptual modeling, problem-solving techniques, and refactoring.  This is how Brodie describes the book himself:</p><blockquote><p>&#8220;We need a consistent and practical methodology for thinking about software problems. That is what I have tried to capture in this book. Thinking Forth is meant for anyone interested in writing software to solve problems. It focuses on design and implementation; deciding what you want to accomplish, designing the components of the system, and finally building the program.&#8221;</p></blockquote><p>If you&#8217;re old-fashioned like me, you&#8217;ll want a <a
href="http://www.amazon.com/dp/0976458705?tag=hashedbits-20">dead-tree version</a>.  The book is published under the Creative Commons license, so you can download the PDFs for free from the <a
href="http://thinking-forth.sourceforge.net">Thinking Forth Project</a> website.</p><p>Thinking Forth was first published in 1984. It was around that time when <a
href="http://hackerboss.com/the-programming-high/">I wrote my first computer program</a>.  This is certainly one of the books I wish I had read sooner.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/thinking-forth-the-unsung-classic/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>The Birth of the Grumpy Asshole Programmer</title><link>https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/</link> <comments>https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/#comments</comments> <pubDate>Wed, 30 Sep 2009 20:26:26 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Humor]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[career]]></category> <category><![CDATA[funny]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[teamwork]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1114</guid> <description><![CDATA[
This is a story, based on true life, on how you turn from a happy programmer into something sinister.
Stage 1: The happy creative programmer
You&#8217;re developing a new exciting product.  You&#8217;re the senior programmer in a small and talented team.  You&#8217;re responsible for a lot of the core functionalities - you get to write a lot [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/" title="Permanent link to The Birth of the Grumpy Asshole Programmer"><img
class="post_image alignnone" src="http://hackerboss.com/pics/jekyll-hyde.jpg" width="350" height="394" alt="Post image for The Birth of the Grumpy Asshole Programmer" /></a></p><p><span
class="drop_cap">T</span>his is a story, based on true life, on how you turn from a happy programmer into something sinister.</p><h3>Stage 1: The happy creative programmer</h3><p>You&#8217;re developing a new exciting product.  You&#8217;re the senior programmer in a small and talented team.  You&#8217;re responsible for a lot of the core functionalities <strong>- you get to write a lot of code and make a lot of the important design decisions. </strong> Things go swimmingly, and you&#8217;re having the time of your life.</p><h3>Stage 2: The proud father</h3><p>You and your team ship the first version of the product.  Despite the highly embarrassing bug in the installer, someone buys it.  You&#8217;re now spending most of your time on improvements, bug fixing, and polishing the existing features.  It&#8217;s not quite as fun as implementing all that new stuff, but still very rewarding. <strong> It&#8217;s your baby, and you want to take care of it.</strong></p><h3>Stage 3: The product guru</h3><p>You&#8217;ve ironed out the biggest kinks, and the product is selling well.  Your user base is growing, and you&#8217;re busy planning what cool features to put in the next big release.<strong> However, with the growing number of users, the support requests start rolling in. </strong> The support engineers don&#8217;t yet quite know the product, but you&#8217;re happy to help (your baby).  By now, there&#8217;s enough questions and inquiries coming your way to be a bit of a distraction, but you can still find stretches of a couple of hours or even a full afternoon here and there to work on the next version.</p><h3>Stage 4: The grumpy asshole programmer</h3><p>The next big version ships.  The customer base keeps growing still, and together with it, the volume of tricky problems grows fast.  The support staff is competent enough to take care of all the easy cases, so<strong> you&#8217;re left with the hairiest problems</strong>.  Since you&#8217;ve been so helpful in the past (your baby), many people have developed a habit of just coming to you when they encounter a problem they can&#8217;t immediately handle themselves.  You try to counter by producing documentation, and it helps a little.  Still, you spend an increasing fraction of afternoons with a <strong>queue outside your door.</strong></p><p>Finally, you develop a fatalistic attitude about getting anything done.  You&#8217;re still the lead developer.  How in the hell are you supposed to get anything done when there&#8217;s someone constantly bothering you about how this-or-that works, requesting help in troubleshooting customer issues, and demanding estimates on how long it would take to add this-and-that feature?  Before, you got almost no email.  Now, you&#8217;re afraid to open your email.  In fact, you avoid opening your email before lunch just so you could get something done.  In response, people begin calling your mobile and checking by your office if you don&#8217;t answer their email in 10 minutes.  <strong>You stop even trying to code, because you would be interrupted anyway.</strong></p><p><strong>You stop being nice to people</strong>, hoping that they would in turn stop asking you things.  It doesn&#8217;t help, since you&#8217;re the resident expert on the product.  You throw empty Pepsi cans at people coming to your door, and fantasize about throwing full ones. You hide in meeting rooms and turn off your phone.  In the evenings, you fashion tiny phallic figurines out of Blu-Tack and stick them on product managers&#8217; doors.   None of this helps much, but it kind of makes you feel better.</p><p>No matter what you try, you are trapped and there is no escape.  <strong>You have become the grumpy asshole programmer.</strong></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-birth-of-the-grumpy-asshole-programmer/feed/</wfw:commentRss> <slash:comments>32</slash:comments> </item> <item><title>Putting Things in Perspective: What is Expensive, What is Cheap?</title><link>https://hackerboss.com/putting-things-in-perspective/</link> <comments>https://hackerboss.com/putting-things-in-perspective/#comments</comments> <pubDate>Sun, 27 Sep 2009 20:50:54 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[costs]]></category> <category><![CDATA[tools]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1077</guid> <description><![CDATA[
This is a breakdown of yearly expenses for one software developer (in USD), highly irresponsibly gathered from various sources on the internet.  For illustrative purposes only, parts may be missing, your mileage will vary, batteries not included.  But, I think it&#8217;s not that far from the truth.
So, what does this picture tell me?  Lots of [...]No related posts.]]></description> <content:encoded><![CDATA[<p></p><p><img
class="alignnone" src="http://hackerboss.com/pics/perspective.png" alt="" width="362" height="408" /></p><p><span
class="drop_cap">T</span>his is a breakdown of yearly expenses for one software developer (in USD), highly irresponsibly gathered from various sources on the internet.  For illustrative purposes only, parts may be missing, your mileage will vary, batteries not included.  But, I think it&#8217;s not <em>that</em> far from the truth.</p><p>So, what does this picture tell me?  Lots of things.</p><p>The opportunity to save on, say, office chairs is <em>extremely limited.</em></p><p>You really really don&#8217;t want high turnover.  Any extra salaries you have to pay <em>really hurts.</em></p><p>Spending an extra 20% on an extra nice office is worth it, if you get an extra 2% of productivity from your developers that way.  That&#8217;s about 9 minutes per day.</p><p>You want to maximize the bang for the buck you get from the big fat red blob.  If you don&#8217;t give your software developers proper tools, such as two good monitors, plenty of RAM, and a proper chair, <em>you are a raving lunatic.</em></p><p>What does the picture tell you?  What does it tell to your boss?  Your CFO?</p><p><strong>Update:</strong> The references for this data:<br
/> <a
href="http://www.payscale.com/research/US/Job=Software_Engineer_%2F_Developer_%2F_Programmer/Salary">PayScale &#8211; Software Developer Salary, Average Salaries</a><br
/> <a
href="http://web.mit.edu/e-club/hadzima/how-much-does-an-employee-cost.html">How much does an employee cost?</a><br
/> <a
href="http://www.bdcnetwork.com/article/CA6663828.html">IFMA workplace study: Average space per employee</a><br
/> <a
href="http://www.informit.com/articles/article.aspx?p=1393497">InformIT: The Cost of Managing Paper: A Great Incentive to Go Paperless!</a><br
/> <a
href="http://www.towersperrin.com/tp/showdctmdoc.jsp?url=Master_Brand_2/USA/News/Spotlights/2009/Jan/2009_01_15_spotlight_2009_HCCS.htm">2009 Health Care Cost Survey Reveals High-Performing Companies Gain Health Dividend</a><br
/> <a
href="http://www.bizrate.com/office-furniture/herman-miller-chairs-for-sale/">Herman Miller chairs prices</a> (assumed to last 10 years)<br
/> Prices for monitors and RAM you can check e.g. at <a
href="http://www.newegg.com">newegg</a>.   Assumed to last a year or two.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/putting-things-in-perspective/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Overriding System Functions for Fun and Profit</title><link>https://hackerboss.com/overriding-system-functions-for-fun-and-profit/</link> <comments>https://hackerboss.com/overriding-system-functions-for-fun-and-profit/#comments</comments> <pubDate>Wed, 23 Sep 2009 20:24:58 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[C]]></category> <category><![CDATA[hack]]></category> <category><![CDATA[unix]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=1014</guid> <description><![CDATA[
Selectively overriding functions in shared libraries is a little known but simple enough trick.  You too can replace system functions with your own versions, or hook into them to add extra functionality.
What follows works as-is on most Linux distributions.  For other Unix flavors you may need to tweak a thing or four, but [...]Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/is-your-regex-matcher-up-to-snuff/' rel='bookmark' title='Permanent Link: Is Your Regex Matcher Up to Snuff?'>Is Your Regex Matcher Up to Snuff?</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/overriding-system-functions-for-fun-and-profit/" title="Permanent link to Overriding System Functions for Fun and Profit"><img
class="post_image alignnone" src="http://hackerboss.com/pics/detour.jpg" width="425" height="282" alt="Post image for Overriding System Functions for Fun and Profit" /></a></p><p><span
class="drop_cap">S</span>electively overriding functions in shared libraries is a little known but simple enough trick.  You too can replace system functions with your own versions, or hook into them to add extra functionality.</p><p>What follows works as-is on most Linux distributions.  For other Unix flavors you may need to tweak a thing or four, but the general principle is the same.</p><h3>Dynamic linker basics</h3><p>Executable programs almost always depend on a number of shared libraries.  The exception is statically linked executables, but they are nowadays exceedingly rare. You can list shared library dependencies with the <code>ldd</code> command.  For example, <code>/bin/date</code> depends on a number of libraries:</p><div
class="wp_syntax"><div
class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">ldd</span> <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">date</span>
        linux-vdso.so.1 =<span style="color: #000000; font-weight: bold;">&gt;</span>  <span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00007fffd51fe000<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        librt.so.1 =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>librt.so.1 <span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00007f0dccd6b000<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        libc.so.6 =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>libc.so.6 <span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00007f0dcca09000<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        libpthread.so.0 =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>libpthread.so.0 <span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00007f0dcc7ed000<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">/</span>lib64<span style="color: #000000; font-weight: bold;">/</span>ld-linux-x86-64.so.2 <span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00007f0dccf74000<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div><p>When you execute a program, the dynamic linker looks at this list of libraries.  It locates the libraries on the filesystem based on configuration files and environment variables, loads the libraries into memory, links the pieces together to make a working whole, and finally executes the program.</p><p>The dynamic linker on most modern Unix flavors has a feature where you can load additional libraries to programs and selectively override functions in other shared libraries.  On Linux, this feature is available via the <code>LD_PRELOAD</code> environment variable.</p><h3>How to override functions</h3><p>Notice &#8220;libc.so.6&#8243; on the <code>ldd</code> output?  That&#8217;s the C library.  It provides the functions in the standard C library, such as <code>malloc()</code>, <code>printf()</code>, and <code>localtime()</code>.</p><p>To override a particular function, you simply build a shared library which exports that function.  You can get a hold of the original definition of the function using <code>dlsym</code>.  Here&#8217;s a minimal example:</p><p><code>datehack.c:</code></p><div
class="wp_syntax"><div
class="code"><pre class="c"><span style="color: #339933;">#define _GNU_SOURCE</span>
<span style="color: #339933;">#include &lt;time.h&gt;</span>
<span style="color: #339933;">#include &lt;dlfcn.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #993333;">struct</span> tm <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>orig_localtime<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> time_t <span style="color: #339933;">*</span>timep<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">struct</span> tm <span style="color: #339933;">*</span>localtime<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> time_t <span style="color: #339933;">*</span>timep<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  time_t t <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>timep <span style="color: #339933;">-</span> <span style="color: #0000dd;">60</span> <span style="color: #339933;">*</span> <span style="color: #0000dd;">60</span> <span style="color: #339933;">*</span> <span style="color: #0000dd;">24</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> orig_localtime<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>t<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span>
_init<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Loading hack.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  orig_localtime <span style="color: #339933;">=</span> dlsym<span style="color: #009900;">&#40;</span>RTLD_NEXT<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;localtime&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div><p>Build this into a shared library:</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-Wall</span> <span style="color: #660033;">-fPIC</span> <span style="color: #660033;">-DPIC</span> <span style="color: #660033;">-c</span> datehack.c
<span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-shared</span> <span style="color: #660033;">-o</span> datehack.so datehack.o <span style="color: #660033;">-ldl</span></pre></div></div><p>And we&#8217;re ready to roll:</p><div
class="wp_syntax"><div
class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">date</span>
Wed Sep <span style="color: #000000;">23</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">56</span>:08 EEST <span style="color: #000000;">2009</span>
$ <span style="color: #007800;">LD_PRELOAD</span>=.<span style="color: #000000; font-weight: bold;">/</span>datehack.so <span style="color: #c20cb9; font-weight: bold;">date</span>
Loading hack.
Tue Sep <span style="color: #000000;">22</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">11</span> EEST <span style="color: #000000;">2009</span>
$</pre></div></div><p>Hey presto!  When <code>datehack.so</code> is loaded, we get yesterday&#8217;s time from <code>localtime</code>.  As you can see, the <code>_init()</code> function is a bit special: it is called automatically when the shared library is loaded into the host process.</p><h3>Some fun</h3><p>In the <a
href="http://hackerboss.com/approximate-regex-matching-in-python/">previous post</a> I already mentioned <a
href="http://laurikari.net/tre/">libtre</a>.  Here&#8217;s a trick you can do to introduce approximate matching capability to any (dynamically linked) binary which uses the POSIX regex API.</p><p>First, compile libtre with the system ABI compatibility enabled:</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>laurikari.net<span style="color: #000000; font-weight: bold;">/</span>tre<span style="color: #000000; font-weight: bold;">/</span>tre-0.8.0.tar.bz2
<span style="color: #c20cb9; font-weight: bold;">tar</span> xjf tre-0.8.0.tar.bz2
<span style="color: #7a0874; font-weight: bold;">cd</span> tre-0.8.0
.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--enable-system-abi</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div><p>Then load it in your favorite program.  I use &#8220;<code>less</code>&#8221; a lot so let&#8217;s use that as an example.  Let&#8217;s run it on the TRE README file:</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #007800;">LD_PRELOAD</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>libtre.so.5 <span style="color: #c20cb9; font-weight: bold;">less</span> README</pre></div></div><p>To do a regex search, enter <code>/</code> followed by your regex.  Try this:</p><pre>/\&lt;(complier){~3}\&gt;</pre><p>The above regex uses libtre&#8217;s syntax for approximate matching to match &#8220;complier&#8221; within tree errors.  The <code>\&lt;</code> and <code>\&gt;</code> match at the beginning and end of a word, so the regex won&#8217;t match partial words.</p><p>This search turns up matches for words like &#8220;compliant&#8221;, &#8220;complete&#8221;, &#8220;compiled&#8221;, and &#8220;compiler&#8221;.</p><h3>Not just a toy</h3><p>There are a bunch of tools which use the <code>LD_PRELOAD</code> trick for something useful.  Perhaps the most common use is overriding <code>malloc()</code>, <code>free()</code>, and friends to detect memory leaks and such.  One of the best such tools is <a
href="http://valgrind.org">Valgrind</a>.  Valgrind does a whole lot more than just memory leaks, and I highly recommend it especially to C programmers.</p><p>The socksify tool intercepts calls to the <code>connect()</code> function (among others), and reroutes TCP connections through a SOCKS proxy.  That&#8217;s highly useful if your corporation is suffering from a highly paranoid IT department which allows connections only through SOCKS.</p><p><a
href="http://freshmeat.net/projects/fakeroot/">Fakeroot</a> makes it look like you can access the filesystem as root without actually being root.  This allows you to create tarballs and other packages with uid 0 files in them, without having to use root privileges.</p><p>So, there&#8217;s a lot you can do with this little trick.  Your imagination is the limit.  What do you want to override today?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/is-your-regex-matcher-up-to-snuff/' rel='bookmark' title='Permanent Link: Is Your Regex Matcher Up to Snuff?'>Is Your Regex Matcher Up to Snuff?</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/overriding-system-functions-for-fun-and-profit/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Approximate Regex Matching in Python</title><link>https://hackerboss.com/approximate-regex-matching-in-python/</link> <comments>https://hackerboss.com/approximate-regex-matching-in-python/#comments</comments> <pubDate>Sat, 19 Sep 2009 20:58:15 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[fuzzy]]></category> <category><![CDATA[python]]></category> <category><![CDATA[regex]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=965</guid> <description><![CDATA[
We all love a little regex hacking now and then.  I loved it enough to even write a regex matching library called libtre.  The cool thing about this library is that it supports searching for approximate matches.
The approximate matching features of this library are being used for things like improving OCR results, generating [...]Related posts:<ol><li><a
href='https://hackerboss.com/is-your-regex-matcher-up-to-snuff/' rel='bookmark' title='Permanent Link: Is Your Regex Matcher Up to Snuff?'>Is Your Regex Matcher Up to Snuff?</a></li><li><a
href='https://hackerboss.com/how-to-distribute-commercial-python-applications/' rel='bookmark' title='Permanent Link: How to Distribute Commercial Python Applications'>How to Distribute Commercial Python Applications</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/approximate-regex-matching-in-python/" title="Permanent link to Approximate Regex Matching in Python"><img
class="post_image alignnone" src="http://hackerboss.com/pics/needle-in-haystack.jpg" width="283" height="424" alt="Post image for Approximate Regex Matching in Python" /></a></p><p><span
class="drop_cap">W</span>e all love a little regex hacking now and then.  I loved it enough to even write a <a
href="http://laurikari.net/tre/">regex matching library called libtre</a>.  The cool thing about this library is that it supports searching for approximate matches.</p><p>The approximate matching features of this library are being used for things like improving OCR results, generating &#8220;did you mean?&#8221; suggestions for users&#8217; searches, and filtering spam.  The library comes with a 2-clause BSD license so you can use it for pretty much whatever you want.</p><h3>Installing the Python extension</h3><p>The extension works with Python 2.  Python 3 is not yet supported.</p><h4>Windows</h4><p>Install the prebuilt Python extension: <a
href="http://laurikari.net/tre/tre-0.8.0.win32-py2.6.msi">tre-0.8.0.win32-py2.6.msi</a>.  The package works with Python 2.6 from <a
href="http://python.org/download/">python.org</a>.</p><h4>Linux, OS X, and other Unix</h4><p>Although you can probably find <a
href="http://laurikari.net/tre/download/#binaries">prebuilt binaries</a> for your system, the Python extension is usually not included.  First, either install some of those binaries or compile from source:</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>laurikari.net<span style="color: #000000; font-weight: bold;">/</span>tre<span style="color: #000000; font-weight: bold;">/</span>tre-0.8.0.tar.bz2
<span style="color: #c20cb9; font-weight: bold;">tar</span> xjvf tre-0.8.0.tar.bz2
<span style="color: #7a0874; font-weight: bold;">cd</span> tre-0.8.0
.<span style="color: #000000; font-weight: bold;">/</span>configure
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div><p>Then, build and install the Python extension:</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #7a0874; font-weight: bold;">cd</span> python
<span style="color: #7a0874; font-weight: bold;">umask</span> 022
<span style="color: #c20cb9; font-weight: bold;">sudo</span> python setup.py <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div><h3>Taking it for a test drive</h3><p>The first thing you can try is run the example program included with the extension.  Here&#8217;s the code for <code>example.py</code>:</p><div
class="wp_syntax"><div
class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> tre
&nbsp;
pt = tre.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Don(ald)?( Ervin)? Knuth&quot;</span>, tre.<span style="color: black;">EXTENDED</span><span style="color: black;">&#41;</span>
data = <span style="color: #483d8b;">&quot;&quot;&quot;
In addition to fundamental contributions in several branches of
theoretical computer science, Donnald Erwin Kuth is the creator of
the TeX computer typesetting system, the related METAFONT font
definition language and rendering system, and the Computer Modern
family of typefaces.
&quot;&quot;&quot;</span>
&nbsp;
fz = tre.<span style="color: black;">Fuzzyness</span><span style="color: black;">&#40;</span>maxerr = <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> fz
m = pt.<span style="color: black;">search</span><span style="color: black;">&#40;</span>data, fz<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> m:
    <span style="color: #ff7700;font-weight:bold;">print</span> m.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> m<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span></pre></div></div><p>When you run <code>example.py</code> the output should look like this:</p><pre>tre.Fuzzyness(delcost=1,inscost=1,maxcost=2147483647,subcost=1, maxdel=2147483647,maxerr=3,maxins=2147483647,maxsub=2147483647)
((95, 113), (99, 108), (102, 108))
Donnald Erwin Kuth</pre><p>So what does this program do?  First we compile the regex <code>Don(ald( Ervin)?)? Knuth</code>.  This simple regex matches any of the following three strings:</p><ul><li>Donald Ervin Knuth</li><li>Donald Knuth</li><li>Don Knuth</li></ul><p>The interesting part is obviously this:</p><div
class="wp_syntax"><div
class="code"><pre class="python">fz = tre.<span style="color: black;">Fuzzyness</span><span style="color: black;">&#40;</span>maxerr = <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
m = pt.<span style="color: black;">search</span><span style="color: black;">&#40;</span>data, fz<span style="color: black;">&#41;</span></pre></div></div><p>This searches for an <em>approximate</em> match to the regex in <code>data</code>, with at most three errors.  The search finds &#8220;Donnald Erwin Kuth&#8221; which matches our regex within those three errors.</p><h3>Some more details</h3><p>The <code>tre</code> module contents are similar to the contents of the <code>re</code> module which comes with Python.  Here are the key parts:</p><p><strong>tre.compile(</strong><em>pattern</em><strong>[, </strong><em>flags</em><strong>])</strong><br
/> Compiles a regex pattern into a regex object.  The regex object can then be used to search for approximate matches using its <code>search()</code> method.</p><p
class="alert">A warning about regex syntax: this library uses the <a
href="http://laurikari.net/tre/documentation/regex-syntax/">POSIX regex syntax</a>, which is not 1:1 compatible with the usual Python regex syntax.</p><p><strong>tre.Fuzzyness([</strong><em>delcost=1</em><strong>, </strong><em>inscost=1</em><strong>, </strong><em>subcost=1</em><strong>, </strong><em>maxcost=&lt;unlimited&gt;</em><strong>, </strong><em>maxdel=&lt;unlimited&gt;</em><strong>, </strong><em>maxins=&lt;unlimited&gt;</em><strong>, </strong><em>maxsub=&lt;unlimited&gt;</em><strong>, </strong><em>maxerr=&lt;unlimited&gt;</em><strong>])</strong><br
/> Creates a &#8220;fuzzyness&#8221; object, used with the <code>search()</code> method to restrict the number of errors allowed.</p><p><strong>RegexObject.search(</strong><em>string</em><strong>, </strong><em>fuzzyness</em><strong>[, </strong><em>flags</em><strong>])</strong><br
/> Searches for a match in the string with the given fuzzyness.</p><p>So, as usual with regex libraries, you first compile a regex and then use it to find matches.  The fuzzyness object defines how many errors of which kinds the match is allowed to have.  The different kinds of errors are:</p><ul><li><em>insertion</em>: an extra character, like changing Donald to Donnald</li><li><em>deletion</em>: a missing character, like changing Knuth to Kuth</li><li><em>substitution</em>: a changed character, like changing Ervin to Erwin</li></ul><p>The total number of allowed errors is controlled by the <code>maxerr</code> field.  This is probably enough for most applications.</p><p>For more fine-grained control, the maximum number of errors can be controlled for each error type separately with <code>maxins</code>, <code>maxdel</code>, and <code>maxsub</code>.  The allowed errors can also be limited using <em>costs</em>.  The default cost of each error is one, but can be set to any value using <code>inscost</code>, <code>delcost</code>, and <code>subcost</code>. The maximum cost is set with <code>maxcost</code>.</p><p>There&#8217;s a lot more I could say, but I&#8217;ll save my breath for further posts.  I&#8217;ll just close with a modification on the by now old regex matching adage <a
href="http://regex.info/blog/2006-09-15/247">first uttered in 1997</a>:</p><blockquote><p>Some people, when confronted with a problem, think “I know, I&#8217;ll use regular expressions with approximate matching.”   Now they have, like, maybe three or so problems.</p></blockquote><p>Related posts:<ol><li><a
href='https://hackerboss.com/is-your-regex-matcher-up-to-snuff/' rel='bookmark' title='Permanent Link: Is Your Regex Matcher Up to Snuff?'>Is Your Regex Matcher Up to Snuff?</a></li><li><a
href='https://hackerboss.com/how-to-distribute-commercial-python-applications/' rel='bookmark' title='Permanent Link: How to Distribute Commercial Python Applications'>How to Distribute Commercial Python Applications</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/approximate-regex-matching-in-python/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Programming Problems in Disguise</title><link>https://hackerboss.com/programming-problems-in-disguise/</link> <comments>https://hackerboss.com/programming-problems-in-disguise/#comments</comments> <pubDate>Sat, 12 Sep 2009 18:15:33 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[data-driven]]></category> <category><![CDATA[dsl]]></category> <category><![CDATA[languages]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=941</guid> <description><![CDATA[
Have you ever written a parser for a configuration file?  Or a data driven interpreter which walks through data, and dispatches appropriate actions?  I&#8217;ve written too many to count, and more than half of them were a waste of time. They were a waste of time because they were programming problems in disguise.
A classical disguised [...]Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/programming-problems-in-disguise/" title="Permanent link to Programming Problems in Disguise"><img
class="post_image alignnone" src="http://hackerboss.com/pics/disguise.jpg" width="425" height="282" alt="Post image for Programming Problems in Disguise" /></a></p><p>Have you ever written a parser for a configuration file?  Or a data driven interpreter which walks through data, and dispatches appropriate actions?  I&#8217;ve written too many to count, and more than half of them were a waste of time.<strong> </strong>They were a waste of time because they were programming problems in disguise.</p><p><strong>A classical disguised programming problem is makefiles.</strong> Traditional tools, such as make, treat building programs as a configuration problem.  For make, you create a configuration file to define what programs to build, what commands to run to generate each target, and so on.  For a simple project, makefiles work fine.  Sometimes, though, your build process is a bit more complicated.</p><p>Maybe you have to do a slightly different thing on different platforms.  Perhaps you&#8217;d like to avoid listing source code files, instead using a naming convention to indicate which files to build.  Or maybe you find that the makefiles have a lot of repetition which could be eliminated if you just could define some kind of an abstraction to reuse that piece of logic everywhere you need it. As a sidenote, there are some enlightened build tools which correctly treat building programs as a programming problem.  <a
href="http://www.scons.org/">SCons</a> is one of these tools, and I encourage you to check it out.</p><p>The appropriate solution to a programming problem is straight up code. <strong> Instead of a configuration file parser or a data driven interpreter, write a library. </strong> Instead of a configuration file or input for your interpreter, you write normal code using your library.  You get to enjoy the power and flexibility of a real programming language, and you don&#8217;t need to implement any of it yourself.</p><p>Occasionally, you really do need to provide a closed interface with some kind of mini language, because that just the way it is.  Most regex APIs, for example, compile strings into regex objects.  But there is no reason why you cannot <em>also</em> provide an API to programmatically build regex objects without having to go through the stupid strings.</p><p>Here are some <strong>telltale signs to detect a disguised programming problem:</strong></p><ul><li>You have to generate configuration files to work around limitations.</li><li>The configuration file format has grown abstraction capabilities like functions, macros, and reusable variables.</li><li>The configuration allows embedding code.</li><li>In general, any features which smell like a programming language: loops, inheritance, namespaces, types, and so on.</li></ul><p>So the next time you find yourself writing a configuration file parser or interpreter, note that you are writing that program in a perfectly good programming language.  Why not use it?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li><li><a
href='https://hackerboss.com/overriding-system-functions-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Overriding System Functions for Fun and Profit'>Overriding System Functions for Fun and Profit</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/programming-problems-in-disguise/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Why Your Metrics Suck</title><link>https://hackerboss.com/why-your-metrics-suck/</link> <comments>https://hackerboss.com/why-your-metrics-suck/#comments</comments> <pubDate>Mon, 07 Sep 2009 12:19:46 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[metrics]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=902</guid> <description><![CDATA[
They say you can&#8217;t control what you can&#8217;t measure.  How else would you know if it&#8217;s getting better or worse, right? This is true, sort of, if you know what you&#8217;re doing.
You can measure the weather but you can&#8217;t control it. What you measure, and how, sets limits to how useful your measurements can [...]No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/why-your-metrics-suck/" title="Permanent link to Why Your Metrics Suck"><img
class="post_image alignnone" src="http://hackerboss.com/pics/barometer.jpg" width="426" height="282" alt="Post image for Why Your Metrics Suck" /></a></p><p><span
class="drop_cap">T</span>hey say you can&#8217;t control what you can&#8217;t measure.  How else would you know if it&#8217;s getting better or worse, right? This is true, sort of, if you know what you&#8217;re doing.</p><p><strong>You can measure the weather but you can&#8217;t control it.</strong> What you measure, and how, sets limits to how useful your measurements can be for making improvements.  In this post I&#8217;ll explain what is a useful metric, and show a way to maximize the useful impact of metrics in your organization.</p><h3>How useful can you get?</h3><p>First, a definition.  The <em>complexity</em> of a metric is the somewhat subjective complexity of the system being measured.  The lines of code produced per day is a simple metric.  The corporate operating profit is a complex metric.</p><p>The <em>actionability</em> is the ease at which you can choose clear actions to help improve the reading for a metric.  Yes, &#8220;actionability&#8221; is a word.  I found it on the interwebs.</p><p>Let&#8217;s draw this relationship into a chart:</p><p><img
class="alignnone" src="http://hackerboss.com/pics/metric-actionability.png" alt="" width="425" height="280" /></p><p>When the metric is simple (lines of code) , then the actions to improve results for that metric are clear (learn to cut&#8217;n'paste, duh).  When the metric is complex (operating profit), then the actions to improve results are not so clear.  As the metrics get more complex, it quickly becomes harder to figure out what to do to improve.</p><p>In short, <strong>complex metrics suck</strong> if you want to use them to figure out what to do about the results.</p><p>There&#8217;s a similar relationship between alignment of metrics with high level goals:</p><p><img
class="alignnone" src="http://hackerboss.com/pics/metric-alignment.png" alt="" width="425" height="280" /></p><p>This chart show us that  <strong>simple metrics suck</strong> because they&#8217;re not connected to your high level goals at all.</p><p
style="text-align: left;">To be really useful, a metric should be both easy to act upon <em>and</em> aligned with the high level goals.  Putting this in the form of an equation, we get:</p><p
style="text-align: center;">usefulness = actionability × alignment</p><p>Multiplying the two charts above together gives this, with staggering mathematical precision:</p><p><img
class="alignnone" src="http://hackerboss.com/pics/metric-usefulness.png" alt="" width="425" height="280" /></p><p>Not very encouraging, huh? <strong>At best, metrics are barely above useless. </strong> But it&#8217;s really true.  There is no single metric which would be directly connected to your bottom line and at the same time be really easy to convert into simple steps to improve the results.  There is no silver bullet.</p><p>This chart gives us another useful piece of information. The most useful metrics are the ones in the middle of the complexity scale.  The useful ones leave room for an inductive leap or two to both directions, so everyone gets to actually use their brain.  That can&#8217;t be bad.</p><p
class="alert">This may look like science, but in reality this is only my opinion. Multiplying random functions together may make you twitch, and rightfully so.  There is no body of research where I&#8217;m drawing this from, just my personal experience.</p><h3>Using metrics in your R&amp;D</h3><p>My recommendation is something called <strong>metric of the month</strong>.  In metric of the month, you choose a problem area for the next month.  Then you try to find the best metric which is connected to that problem.  Run with the metric for one month, try to improve the reading as much as you can, and then throw the metric away.  Start over with a new metric for the next month.</p><p>This way you can maximize on the excitement of the fast initial progress with a new metric.  Our <a
href="http://hackerboss.com/coffee-warning/">compilation warning chart</a> is no longer useful to us, for example.  It has lost it&#8217;s mojo.  So, it makes sense to change focus as soon as that happens, and <strong>pick the low hanging fruit from a new area</strong>.  It keeps things improving, and helps keep things interesting.</p><p>Whatever you do, don&#8217;t tell developers to improve on a metric like the corporate operating profit, EBIT, the stock price, or anything like that.  You could just as well tell them to control the weather.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/why-your-metrics-suck/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Inside Tips for Making Me Hire You</title><link>https://hackerboss.com/making-me-hire-you/</link> <comments>https://hackerboss.com/making-me-hire-you/#comments</comments> <pubDate>Wed, 02 Sep 2009 20:59:52 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[career]]></category> <category><![CDATA[hiring]]></category> <category><![CDATA[interviewing]]></category> <category><![CDATA[jobs]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=871</guid> <description><![CDATA[
My post on recruitment mistakes was intended for managers trying to find software developers.  This post is for those on the other side of the table: you, the developer, trying to land a job.  Here&#8217;s how to make your job application stand out, and how to impress me in the subsequent interview.
This is [...]Related posts:<ol><li><a
href='https://hackerboss.com/recruitment-mistakes/' rel='bookmark' title='Permanent Link: Do You Make These Mistakes When Recruiting Software Developers?'>Do You Make These Mistakes When Recruiting Software Developers?</a></li><li><a
href='https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/' rel='bookmark' title='Permanent Link: 6 Tips for Small Software Vendors to Understand Enterprise Customers'>6 Tips for Small Software Vendors to Understand Enterprise Customers</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/making-me-hire-you/" title="Permanent link to Inside Tips for Making Me Hire You"><img
class="post_image alignnone" src="http://hackerboss.com/pics/secret.jpg" width="425" height="282" alt="Post image for Inside Tips for Making Me Hire You" /></a></p><p><span
class="drop_cap">M</span>y post on <a
href="http://hackerboss.com/recruitment-mistakes/">recruitment mistakes</a> was intended for managers trying to find software developers.  This post is for those on the other side of the table: you, the developer, trying to land a job. <strong> Here&#8217;s how to make your job application stand out, and how to impress me in the subsequent interview.</strong></p><p>This is written purely from my personal perspective.  If you want <em>me</em> to hire you, this is the perfect guide for that. For other managers, your mileage will vary.  Wildly.</p><h3>Your application</h3><p>The application is usually my first point of contact with you.  Make it count.  Here are the most important questions I want your application to answer:</p><h4>Do you have the required skills?</h4><p>It&#8217;s all about the skills.  <strong>You need to have them, and your application must make it clear what your skills are.</strong> I&#8217;m looking for real experience in any and all areas of producing software: programming, testing, design, specifications, version control, build systems, tech support, maintenance, optimizing, documentation, algorithms, project management, debugging, IDEs, tools.   The more you know the better.</p><h4>Do you get things done?</h4><p>While talking about software is fun, we need to actually build some every now and then. I need to know that you are someone who gets things done. So<strong> be specific about what you&#8217;ve done in the past</strong>.  I don&#8217;t want to hear how &#8220;you played an important role in the development of the Fnorb Buzz product suite&#8221;.  I want to know what you did exactly, in plain engineer speak.   Did you write code? Specs?  Run tests? Manage projects?  What tools did you use? What did you learn?</p><h4>Are you passionate?</h4><p>I&#8217;m looking for signs of passion.  Passion for developing software, of course &#8211; while passion for martial arts or cultivating Spanish snails are nice, it&#8217;s not what I&#8217;m primarily looking for in a software developer.<strong> If you spend time with software and computers on your free time, please don&#8217;t keep it a secret</strong>.  It&#8217;s always cool to read about how you set up off-site backups for your mom with some cron jobs, rsync, and shell scripts, or about that data center you built in your closet.</p><h4>Are you a good communicator?</h4><p>I don&#8217;t want to read a 15-page account on every single computer related thing you&#8217;ve ever done.<strong> Keep it short, sweet, and relevant.</strong> Try to put yourself in my shoes &#8211; what is it about yourself that I would find interesting?  I need to know about your skills and what you can do.  What compelling evidence do you have to showcase your awesomeness?</p><p>That&#8217;s all, really.  If it seems that you&#8217;re not lacking in any of these departments, I&#8217;m not going to throw your application in the trashcan.  Yet.</p><h3>The phone screen</h3><p>If your application looks interesting, I&#8217;m going to schedule a short phone interview with you.  My main goal is to find out more about your communication skills, but now verbally instead of in written form.  I don&#8217;t have a particular method for doing the call.  I&#8217;ll just ask about things I&#8217;ve jotted down on the margin of your application while reading it.</p><h3>The interview</h3><p>If the phone interview went well, then we&#8217;ll finally get to meet face-to-face. In addition to you and me, there will be one or two other people present in the interview as well.</p><h4>Talking about code</h4><p>I&#8217;m going to make you do a<strong> coding exercise</strong> or two on paper or a whiteboard, or possibly a laptop.</p><p>If I already know for a fact that you can code, I may skip the coding exercise.  In lack of other evidence, I&#8217;ll have to rely on the coding exercise.  I&#8217;ll find out if you can program your way out of a wet paper bag.  Then<strong> I&#8217;ll find out if you can work with code for real.<br
/> </strong></p><p>We talk about code, you write some, and I&#8217;ll find out what you know. I&#8217;ll see how you react when you run into problems, what you do when you get incomplete instructions, and in general how you go about solving problems.</p><h4>Other questions</h4><p>We won&#8217;t just talk about code, of course.  We&#8217;ll try to find out what kind of a person you are, so we can determine if you would fit into our team or not.  Also, we&#8217;ll need to find out some basics about why you&#8217;re looking for a job, what kind of a salary are you hoping for, and so on.  You should want the job for the right reasons.</p><p>My advice for these questions is simply to<strong> be honest</strong>.  Tell me the truth.  Don&#8217;t tell me what you <em>think</em> I want to hear, because that&#8217;s probably not what I <em>really</em> want to hear.</p><p>Towards the end of the interview I&#8217;ll ask if you have any questions about anything.  If you have no questions, I&#8217;m bound to think that you&#8217;re not very enthusiastic about getting the job.  On the other hand, if your questions indicate that you&#8217;re already thinking about what it would be like to work for us, it&#8217;s a good sign.  I wouldn&#8217;t like to hire you if you just need a job, any job.</p><p>So, now you know how I will deal with your application.  To make me hire you, all you need is the skills, the right kind of motivation, and a suitable personality.  Easy, right?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/recruitment-mistakes/' rel='bookmark' title='Permanent Link: Do You Make These Mistakes When Recruiting Software Developers?'>Do You Make These Mistakes When Recruiting Software Developers?</a></li><li><a
href='https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/' rel='bookmark' title='Permanent Link: 6 Tips for Small Software Vendors to Understand Enterprise Customers'>6 Tips for Small Software Vendors to Understand Enterprise Customers</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/making-me-hire-you/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>How to Start Innovating and Make Work Fun Again</title><link>https://hackerboss.com/how-to-start-innovating-and-make-work-fun-again/</link> <comments>https://hackerboss.com/how-to-start-innovating-and-make-work-fun-again/#comments</comments> <pubDate>Thu, 27 Aug 2009 20:56:38 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Management]]></category> <category><![CDATA[deadline]]></category> <category><![CDATA[fun]]></category> <category><![CDATA[motivation]]></category> <category><![CDATA[Productivity]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=829</guid> <description><![CDATA[
Is there always something on your to-do list?  Is your project manager constantly barraging you with task after task after task?  Is there an &#8220;innovation initiative&#8221; going on in your company, but somehow nobody seems to be doing all that innovating?
If this sounds like your company, I have good news for you.  [...]Related posts:<ol><li><a
href='https://hackerboss.com/you-dont-need-a-deadline/' rel='bookmark' title='Permanent Link: You Don&#8217;t Need a Deadline'>You Don&#8217;t Need a Deadline</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/how-to-start-innovating-and-make-work-fun-again/" title="Permanent link to How to Start Innovating and Make Work Fun Again"><img
class="post_image alignnone" src="http://hackerboss.com/pics/mad-scientist.jpg" width="400" height="283" alt="Post image for How to Start Innovating and Make Work Fun Again" /></a></p><p><span
class="drop_cap">I</span>s there always something on your to-do list?  Is your project manager constantly barraging you with task after task after task?  Is there an &#8220;innovation initiative&#8221; going on in your company, but somehow nobody seems to be doing all that innovating?</p><p>If this sounds like your company, I have good news for you.  By the end of this post you&#8217;ll not only understand why your company isn&#8217;t very innovative &#8211; you will also know what <em>you</em> can do about it.</p><h3>The #1 Innovation Killer</h3><p>The one thing responsible for most innovation-stifling in companies today is probably <strong>optimizing human resources for maximum efficiency</strong>.  You know, doing the biggest amount of work possible with the least amount of resources.</p><p>On the surface, it seems like a reasonable thing to strive for.  Why hire five people to do customer support when four people can handle it, if they work hard?  There&#8217;s nothing wrong with working hard, is there?  Why should you be paid for slacking off?</p><p>Well, of course there is nothing wrong with working hard.  But it&#8217;s kind of hard to have a broad mind and think out of the box and, you know, <em>innovate</em>, when there&#8217;s a manager breathing down your neck demanding for a completion date on that critical bug fix.</p><p>One of my old bosses had a fun way to put this.  He said &#8220;<strong>we&#8217;re too busy pushing the bicycle to hop on and start riding</strong>&#8220;.  That&#8217;s exactly what is going on in the 100% efficient organization.  Pushing the bicycle <em>is</em> 100% efficient &#8211; all effort is spent in moving the bicycle.  But it sure isn&#8217;t the most effective way to move a bicycle from A to B.</p><p>In <a
href="http://www.amazon.co.uk/dp/0932633617?tag=hashedbits-20">Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency</a>, Tom DeMarco puts it this way:</p><blockquote><p>In our constant quest to make our organizations more efficient (reduction of overhead, standardization of processes, overworking management and resources), we have actually made them less effective. The solution lies in (re)introducing `slack&#8217;. Slack is the lubricant required to effect change, it is the degree of freedom that enables reinvention and true effectiveness.</p></blockquote><h3>Why You Cannot Innovate Under Pressure</h3><p>Dan Pink recently gave a fantastic talk on the science of motivation. I invite you to watch this video now:</p><p><object
width="500" height="306"><param
name="movie" value="http://www.youtube.com/v/rrkrvAUbU9Y&#038;fs=1"></param><param
name="allowFullScreen" value="true"></param><param
name="allowscriptaccess" value="always"></param><embed
src="http://www.youtube.com/v/rrkrvAUbU9Y&#038;fs=1" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p><p>Did you watch it yet?  Please do, it&#8217;s really worth it.</p><p>I&#8217;ll just wait here until you&#8217;re done&#8230;</p><p>OK, good.</p><p>The key point I want to make here is that <strong>If a task requires even rudimentary cognitive skill, a larger reward leads to poorer performance.</strong> This is a scientific fact, and can be extrapolated from trick questions such as the candle problem to &#8220;real work&#8221;.  See <a
href="http://en.wikipedia.org/wiki/Functional_fixedness#Candle_Box">Functional fixedness</a>.</p><h3>What Should You Do?</h3><p>If you&#8217;re a manager and you can decide on how time is spent in your company, fantastic!  The first thing to try is to have a FedEx day a few times a year.  If you watched the video, you already know what it is: <strong>set aside a day for developers to work on whatever they want</strong> and then demonstrate results to the entire company.  Repeat often.</p><p>If you&#8217;re an executive manager, you may have the power go the Google way.  Decide that your knowledge workers can spend one day a week on whatever they want to.</p><p>If you&#8217;re a developer, show this post to your manager.  Hopefully you can cajole him into trying some of that FedEx.  If not, do a FedEx day or three as a skunkworks project.  Nobody needs to know, right?  Until, of course, when you get some results worth showing.  As they say, sometimes it&#8217;s easier to ask forgiveness than it is to get permission.</p><p>So, pull your nose out of the task list, bug tracker, inbox, or calendar for a while.  <strong>It&#8217;s time to put the fun back into your work.</strong></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/you-dont-need-a-deadline/' rel='bookmark' title='Permanent Link: You Don&#8217;t Need a Deadline'>You Don&#8217;t Need a Deadline</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/how-to-start-innovating-and-make-work-fun-again/feed/</wfw:commentRss> <slash:comments>12</slash:comments> </item> <item><title>How to Distribute Commercial Python Applications</title><link>https://hackerboss.com/how-to-distribute-commercial-python-applications/</link> <comments>https://hackerboss.com/how-to-distribute-commercial-python-applications/#comments</comments> <pubDate>Mon, 24 Aug 2009 20:02:19 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[commercial]]></category> <category><![CDATA[distribution]]></category> <category><![CDATA[packaging]]></category> <category><![CDATA[python]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=801</guid> <description><![CDATA[
Most of us in the software business are not in a position to release our source code to the public.  As much as I love free and open source software, I also understand it&#8217;s not part of all business models.  Python is enjoying commercial success, but perhaps less so in cases where end-users actually install [...]Related posts:<ol><li><a
href='https://hackerboss.com/approximate-regex-matching-in-python/' rel='bookmark' title='Permanent Link: Approximate Regex Matching in Python'>Approximate Regex Matching in Python</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/the-shell-is-like-a-dishwasher/' rel='bookmark' title='Permanent Link: The Shell is Like a Dishwasher'>The Shell is Like a Dishwasher</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/how-to-distribute-commercial-python-applications/" title="Permanent link to How to Distribute Commercial Python Applications"><img
class="post_image alignnone" src="http://hackerboss.com/pics/bubble-wrap.jpg" width="424" height="283" alt="Bubble wrap." /></a></p><p><span
class="drop_cap">M</span>ost of us in the software business are not in a position to release our source code to the public.  As much as I love free and open source software, I also understand it&#8217;s not part of all business models.  Python is enjoying commercial success, but perhaps less so in cases where end-users actually install the software.</p><p>Distributing applications written in Python can be tricky, especially if you don&#8217;t want to distribute your source code. I set out to find out how exactly do you distribute a Python program, sans source code, on various operating systems.  It turns out there are quite a few alternatives to consider.</p><p>In each alternative, the first step is to compile your code to bytecode (.pyc or .pyo).  That&#8217;s what you&#8217;ll be shipping instead of the source code.</p><h2>1. Using a preinstalled Python</h2><p>Nowadays, many operating systems actually come with a sane Python interpreter preinstalled. Most Linux distributions ship with Python, and Mac OS X comes with Python, for example. Windows does not come with Python, nor do most commercial Unix systems.</p><p>Even if a preinstalled Python is available, it may not work for you.  Maybe it&#8217;s an older version, and you want to use the latest and greatest.  Another potential hurdle is that the Python version will be different on different operating systems. Mac OS X 10.5 (Leopard) comes with Python 2.5.1, Mac OS X 10.4 (Tiger) came with Python 2.3.5. Ubuntu 8.04 came with Python 2.5.2, Ubuntu 9.04 comes with Python 2.6.2&#8230; You get the point.</p><p>Sometimes modules are deprecated between versions and you&#8217;ll need to write stuff like this to suppress warnings:</p><div
class="wp_syntax"><div
class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> hashlib
    md5_new = hashlib.<span style="color: #dc143c;">md5</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">md5</span>
    md5_new = <span style="color: #dc143c;">md5</span>.<span style="color: #dc143c;">new</span></pre></div></div><p>Varying Python versions may or may not be a problem for you application.  The example above is actually a fairly bening problem, and it&#8217;s easily solved.  If you ever need to support both Python 3 and Python 2, you will have bigger problems than just deprecated modules.</p><h2>2. Freezing tools</h2><p>Freezing tools compile Python programs to executables. If you&#8217;re distributing a small number of executables, a freeze tool might be just what you need.  There are quite a few of these around.  Disclaimer: I haven&#8217;t used most of these tools.  Caveat emptor.</p><h3>py2exe</h3><p>If you only care about Windows, <a
href="http://www.py2exe.org/">py2exe</a> fits the bill nicely.</p><blockquote><p>py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation.</p></blockquote><p>Applications such as BitTorrent and SpamBayes use py2exe &#8211; so it should be stable.   From what I&#8217;ve read, py2exe  works quite well.</p><h3>py2app</h3><p><a
href="http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html">py2app</a> makes standard Mac OS X application bundles from Python scripts.  It&#8217;s &#8220;py2exe for Mac&#8221;.</p><h3>cx_Freeze</h3><p><a
href="http://cx-freeze.sourceforge.net/">cx_Freeze</a> is similar to py2exe, but claims to be portable to both Windows and Unix systems.</p><h3>bbfreeze</h3><p><a
href="http://pypi.python.org/pypi/bbfreeze/">bbfreeze</a> works on Windows and Unix, but not on OS X.  Originally based on cx_Freeze.</p><h3>Freeze</h3><p>The <a
href="http://wiki.python.org/moin/Freeze">Freeze</a> tool ships with Python.  It compiles Python programs to executables on Unix systems.</p><p>In my simple tests, it was able to handle a trivial hello world application pretty well, if we ignore the size of the resulting executable (several megabytes).  Throwing anything more complex at it tended to fail miserably for various reasons.  It seems to me that Freeze does not work very well out of the box.</p><h3>PyInstaller</h3><p><a
href="http://www.pyinstaller.org/">PyInstaller</a> creates executables for Windows, Linux, and Irix.  Yeah, Irix.</p><h2>3. Bundling CPython with your application</h2><p><a
href="http://en.wikipedia.org/wiki/CPython">CPython</a> is the default, most widely used implementation of Python.  It is written in C.  When people talk about the Python interpreter, they mean CPython unless they explicitly mention <a
href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython">IronPython</a> (for .NET and SilverLight), <a
href="http://www.jython.org/">Jython</a> (for JVM), <a
href="http://www.stackless.com/">Stackless Python</a> (for concurrent programming), or something like that.</p><p>Sometimes the freezing tools aren&#8217;t a good choice.  They might lack platform coverage or could have other problems.  If you&#8217;re distributing a large collection of separate programs the overhead of bundling the full Python interpreter to each program will be prohibitive.  A good alternative is to bundle the Python interpreter with your application yourself.  You gotta love some DIY in the software business, right?</p><p><strong>The first step is to bundle the CPython interpreter with your application.</strong> That&#8217;s <a
href="http://docs.python.org/extending/embedding.html">fairly straightforward</a> if you know what you&#8217;re doing.  You simply include the Python interpreter with your code.</p><p><strong>The second step is to cherry-pick what you need from the Python standard libraries.</strong> Tools like <a
href="http://furius.ca/snakefood/">snakefood</a> or <a
href="http://pypi.python.org/pypi/modulegraph/">modulegraph</a> can help you do that.  From what I can tell, these tools aren&#8217;t perfect, so be prepared to manually fix the results or patch the tools.</p><p><strong>A third and optional step is to customize your Python distribution.</strong> For example, you might inline all bytecode directly into your executables instead of separate files.  Then you can override the loading functions to pass the code directly from memory instead of loading from disk.</p><h2>4. My recommendations</h2><p>My first choice is to use the Python interpreter which comes with your target platform, if it has one.  Use <a
href="http://docs.python.org/distutils/">distutils</a> to install custom modules or extensions. If your application only supports Windows, use <strike>app2exe</strike> py2exe.</p><p>For complex scenarios, my recommendation is to go with bundling CPython yourself and steer clear of the freezers.  If a freezing tool works for you, awesome. You just saved yourself from a lot of trouble.  But if you need to cover a large number of platforms, or your application has special needs from the interpreter, then packaging CPython yourself seems to be the best way to go.</p><p>The added benefit of bundling CPython yourself is that you can customize the interpreter to your heart&#8217;s content.  Not that you&#8217;ll really need to, but it sounds like fun.  There&#8217;s nothing like making your own bubble wrap, complete with a custom hand-painted smiley face on each bubble.</p><p><script>utmx_section("Subscribe link")</script><br
/> <a
href="http://hackerboss.com/subscribe/">Subscribe to Hacker Boss</a> today!</noscript></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/approximate-regex-matching-in-python/' rel='bookmark' title='Permanent Link: Approximate Regex Matching in Python'>Approximate Regex Matching in Python</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/the-shell-is-like-a-dishwasher/' rel='bookmark' title='Permanent Link: The Shell is Like a Dishwasher'>The Shell is Like a Dishwasher</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/how-to-distribute-commercial-python-applications/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Why Write Code When You Can Remove Some?</title><link>https://hackerboss.com/why-write-code-when-you-can-remove-some/</link> <comments>https://hackerboss.com/why-write-code-when-you-can-remove-some/#comments</comments> <pubDate>Thu, 20 Aug 2009 19:17:44 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[architecture]]></category> <category><![CDATA[cleanup]]></category> <category><![CDATA[refactoring]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=772</guid> <description><![CDATA[
Some of the most satisfying commits I&#8217;ve ever done were the ones where I got to remove a lot of old cruft.
As your codebase grows older, it will accrue technical debt.  It comes in many forms, but sometimes the most straightforward cure is to cut the bad parts out.
I&#8217;m not talking just about dead [...]Related posts:<ol><li><a
href='https://hackerboss.com/get-rid-of-templates/' rel='bookmark' title='Permanent Link: Get Rid of Source Code Templates'>Get Rid of Source Code Templates</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/why-write-code-when-you-can-remove-some/" title="Permanent link to Why Write Code When You Can Remove Some?"><img
class="post_image alignnone" src="http://hackerboss.com/pics/surgery.jpg" width="425" height="282" alt="Cutting out some unused bits." /></a></p><p><span
class="drop_cap">S</span>ome of the most satisfying commits I&#8217;ve ever done were the ones where I got to remove a lot of old cruft.</p><p>As your codebase grows older, it will accrue <a
href="http://martinfowler.com/bliki/TechnicalDebt.html">technical debt</a>.  It comes in many forms, but <strong>sometimes the most straightforward cure is to cut the bad parts out.</strong></p><p><strong>I&#8217;m not talking just about dead code.  I&#8217;m talking about obsolete code</strong>.  Obsolete code is code that was there for a reason, but the reason is no longer relevant.  They are the appendixes of software &#8211; still there, still alive, but apparently not serving any useful function.  Cut it out before it gets infected.</p><p>There are some simple tricks and practices to keep tabs on obsolete code.  One of my favorites is the XXX comment:</p><p><code><br
/> // XXX (tag1, tag2): Description<br
/> </code><br
/> You know, like<br
/> <code><br
/> // XXX (obsolete): When 2.0 is released, this won't<br
/> // be needed anymore.<br
/> </code><br
/> or<br
/> <code><br
/> // XXX (bug): <a
href="http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered">drunk, fix later</a><br
/> </code></p><p>It&#8217;s easy, flexible, and greppable.  If you have a lot of code taking care of backwards compatibility, you&#8217;ll want to spend extra attention on making it easy to remove when it becomes obsolete.</p><p>Sometimes, grepping won&#8217;t help and you have to work harder.  To cut out the bad part, you need to shuffle things around, refactor, and build some new pieces.  But the feeling of making it better is totally worth the trouble.</p><p>Don&#8217;t be afraid of deleting obsolete code.  If you ever need it back (and I&#8217;ll bet you won&#8217;t), it&#8217;s going to be right there in your version control history, waiting for you to resurrect it. <strong>Don&#8217;t <code>#if 0</code> or comment it out.  Remove it</strong>. <a
href="http://www.codinghorror.com/blog/archives/000878.html">The best code is no code at all</a>. <a
href="http://www.skrenta.com/2007/05/code_is_our_enemy.html">The code is our enemy</a>.  Don&#8217;t treat the code as an asset.  Treat it as a liability.</p><p>So&#8230; What is going to be your satisfying commit of the day?</p><p><script type="text/javascript">var dzone_url = 'http://hackerboss.com/why-write-code-when-you-can-remove-some/';</script><br
/> <script type="text/javascript">var dzone_title = '[title]';</script><br
/> <script type="text/javascript">var dzone_blurb = '[description]';</script><br
/> <script type="text/javascript">var dzone_style = '2';</script><br
/> <script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script> </p><p>Related posts:<ol><li><a
href='https://hackerboss.com/get-rid-of-templates/' rel='bookmark' title='Permanent Link: Get Rid of Source Code Templates'>Get Rid of Source Code Templates</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/why-write-code-when-you-can-remove-some/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>The Single Most Effective Thing Which Improved My Programming Skills</title><link>https://hackerboss.com/the-single-most-effective-thing-which-improved-my-programming-skills/</link> <comments>https://hackerboss.com/the-single-most-effective-thing-which-improved-my-programming-skills/#comments</comments> <pubDate>Sun, 16 Aug 2009 21:28:26 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[learning]]></category> <category><![CDATA[motivation]]></category> <category><![CDATA[self-help]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=753</guid> <description><![CDATA[
I always thought of myself as a pretty hot-shot programmer.  I had been programming since I was a kid.  It wasn&#8217;t hard to find my first programming job.  Quickly, I recognized that I had much more programming experience than some of my older coworkers.  Comfortable with my skills, I took it easy&#8230;  I took it [...]Related posts:<ol><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/the-single-most-effective-thing-which-improved-my-programming-skills/" title="Permanent link to The Single Most Effective Thing Which Improved My Programming Skills"><img
class="post_image alignnone" src="http://hackerboss.com/pics/punching-bag.jpg" width="425" height="282" alt="Post image for The Single Most Effective Thing Which Improved My Programming Skills" /></a></p><p><span
class="drop_cap">I</span> always thought of myself as a pretty hot-shot programmer.  I had been <a
href="http://hackerboss.com/the-programming-high/">programming since I was a kid</a>.  It wasn&#8217;t hard to find my first programming job.  Quickly, I recognized that I had much more programming experience than some of my older coworkers.  Comfortable with my skills, I took it easy&#8230;  I took it easy for a long time.</p><p>Then, I met a new guy, call him Aaron. Aaron was obviously much better than me in most areas. He was younger than me, too. He made me realize I hadn&#8217;t really improved much in the past years. I was an ad-hoc hacker, and a mediocre one at that.</p><p>This alerted me to <strong>consciously try to improve</strong> myself, and especially the quality of code I write.</p><p>Aaron led me to learn a lot of things. He taught me how most of the code I write will have to be maintained and extended for at least several years, so I should write the code with that in mind. I should write automatic tests for my code. Aaron was always talking about how I should never stop at the first working version, but refactor and refine until the code is elegant.  I discovered that the languages and tools I was using had a lot of room for improvement.</p><p>The most important thing I learned from Aaron was to <strong>never stop learning</strong>.</p><p>After a couple of years, Aaron left the company.  I felt empty.  The past years with him had lifted me to whole new levels of skill, and I realized I was now much better than the rest of the team. They were still writing bad code, and doing the same mistakes as before. I tried to teach them, but they had no interest to learn. In fact, they were annoyed that someone would be so arrogant to tell them what mistakes they were doing.</p><p>Luckily, I was able to change to a small motivated team.  Everyone there was eager to learn more, and I loved it.</p><p>I&#8217;m glad I met Aaron. Without him, I&#8217;d probably still be working with the old gang, going nowhere, and thinking too much of myself.</p><p><small
style="color: #888">This post is based on my answer to a <a
href="http://stackoverflow.com/questions/76364/what-is-the-single-most-effective-thing-you-did-to-improve-your-programming-skill">Stack Overflow question</a>.</small></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-single-most-effective-thing-which-improved-my-programming-skills/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Do You Make These Mistakes When Recruiting Software Developers?</title><link>https://hackerboss.com/recruitment-mistakes/</link> <comments>https://hackerboss.com/recruitment-mistakes/#comments</comments> <pubDate>Wed, 12 Aug 2009 21:17:39 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[hiring]]></category> <category><![CDATA[jobs]]></category> <category><![CDATA[recruiting]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=716</guid> <description><![CDATA[
Picture the last time you were hiring.  Did you have trouble finding the best programmers and technical talent?
Well, chances are you&#8217;re doing it wrong.
Here&#8217;s my top list of big mistakes I&#8217;ve seen or done myself, and some helpful pointers on how to avoid them.
Do you post boring job ads?
The world is full of ordinary and [...]Related posts:<ol><li><a
href='https://hackerboss.com/making-me-hire-you/' rel='bookmark' title='Permanent Link: Inside Tips for Making Me Hire You'>Inside Tips for Making Me Hire You</a></li><li><a
href='https://hackerboss.com/building-high-performance-software-teams/' rel='bookmark' title='Permanent Link: Building High Performance Software Teams'>Building High Performance Software Teams</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/recruitment-mistakes/" title="Permanent link to Do You Make These Mistakes When Recruiting Software Developers?"><img
class="post_image alignnone" src="http://hackerboss.com/wp/wp-content/uploads/flickr/failure.jpg" width="302" height="380" alt="Failed." /></a></p><p><span
class="drop_cap">P</span>icture the last time you were hiring.  Did you have trouble finding the best programmers and technical talent?</p><p>Well, chances are you&#8217;re doing it wrong.</p><p>Here&#8217;s my top list of big mistakes I&#8217;ve seen or done myself, and some helpful pointers on how to avoid them.</p><h3>Do you post boring job ads?</h3><p>The world is full of ordinary and basic job ads.  The first step in the long and rocky road to a successful hire is to get people to make note of your ad.  Spend time crafting a killer job ad which captures developers&#8217; attention.</p><h3>Do you post ads in the wrong places?</h3><p>You have to know your target audience.  Post your ad to the relevant places which great developers follow.  At the moment, one of these places might be <a
href="http://jobs.stackoverflow.com/"> jobs.stackoverflow.com</a>.  These things change quickly, so be sure to follow the trends even though you&#8217;re not looking to hire right now.</p><h3>Do you fail to immediately answer all applications?</h3><p>A long time ago, I applied for a programmer job at a well known Finnish software company.  I sent them my resume but heard nothing back for a long time.  Finally, after several weeks of submitting my application, I received a reply thanking me for my interest in the<em> &#8220;storage attendant job&#8221;</em>, and informed me that unfortunately at this time they cannot hire me.  By then I had already been hired somewhere else.</p><p>You should immediately answer all job applications to let the applicant know that their application was received.  Also inform the applicant on how your recruiting process works, and when should they expect to hear more from you.  Radio silence will never work to your advantage.</p><h3>Do you skip phone interviews?</h3><p>Phone interviews are a great way to quickly find out if the applicant is a good communicator.  Nothing is more frustrating than going through all the trouble of setting up a job interview, only to find out that you can&#8217;t quite grapple a thick Elbonian accent.</p><h3>Do you hire people who &#8220;might be good&#8221;?</h3><p>You should only hire people who are definitely good.  Only hire if you&#8217;re reasonably sure that the person would be a great fit in your team.  The cost for training in a developer are high.  If things don&#8217;t turn out well, you&#8217;ve lost a lot of time and money.  Not quite sure if the candidate would be great?  That&#8217;s a no hire.</p><h3>Do you ignore the local universities?</h3><p>This is a glaring problem at least in Finland &#8211; maybe things are better on other parts of the planet.  Universities are full of smart people.  At some point, these people start looking for their first jobs.  For the best programmers this could well be the <em>only</em> time they are on the job market.  For the rest of their careers they just kind of go work wherever they want.</p><p>You would be wise to build a relationship with the relevant fraternities, sororities, and student guilds.  By &#8220;relationship&#8221;, I mostly mean free beer in exchange of a little attention.  When the students start looking for that first job, your company could well be among the first that springs to mind.</p><h3>Do you not do internships?</h3><p>Summer internships are a fantastic way to get young and motivated people working for you, <em>before</em> they are forever gone from the job market.  It&#8217;s also less risky than flat-out hiring, both for the intern and your company.</p><p>Now, picture again the last time you were hiring.  What would you change if you could do it over again?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/making-me-hire-you/' rel='bookmark' title='Permanent Link: Inside Tips for Making Me Hire You'>Inside Tips for Making Me Hire You</a></li><li><a
href='https://hackerboss.com/building-high-performance-software-teams/' rel='bookmark' title='Permanent Link: Building High Performance Software Teams'>Building High Performance Software Teams</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/recruitment-mistakes/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>6 Tips for Small Software Vendors to Understand Enterprise Customers</title><link>https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/</link> <comments>https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/#comments</comments> <pubDate>Mon, 10 Aug 2009 08:25:30 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Product Management]]></category> <category><![CDATA[corporate]]></category> <category><![CDATA[customers]]></category> <category><![CDATA[enterprise]]></category> <category><![CDATA[isv]]></category> <category><![CDATA[policy]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=658</guid> <description><![CDATA[Building software for enterprise customers is a very different experience from building software for home users, for example.  If you’re working for a small software company, it can be sometimes difficult to understand how big corporations work.Related posts:<ol><li><a
href='https://hackerboss.com/making-me-hire-you/' rel='bookmark' title='Permanent Link: Inside Tips for Making Me Hire You'>Inside Tips for Making Me Hire You</a></li><li><a
href='https://hackerboss.com/platforms-come-with-a-culture/' rel='bookmark' title='Permanent Link: Platforms Come With a Culture'>Platforms Come With a Culture</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/" title="Permanent link to 6 Tips for Small Software Vendors to Understand Enterprise Customers"><img
class="post_image alignnone" src="http://hackerboss.com/wp/wp-content/uploads/2009/08/david_goliath-262x300.jpg" width="262" height="300" alt="David & Goliath" /></a></p><p><span
class="drop_cap">B</span>uilding software for enterprise customers is a very different experience from building software for home users, for example.  If you&#8217;re working for a small software company, it can be sometimes difficult to understand how big corporations work.  Here are some tips based on my experience. Hopefully, these are helpful in figuring out how enterprise customers change some of the expectations for your software.</p><h3>1. Enterprises are big on policy</h3><p>There is a policy for everything.  Even though policies are usually defined in good faith, from the perspective of an individual employee policies are about compliance and not common sense.  So sometimes, a policy will be the only reason which prevents your software from being used, or prevents it from from being configured in the way which would make the most sense.  Don&#8217;t fight the policy windmill.  Work around it.</p><h3>2. Enterprises have long deployment cycles</h3><p>It takes ages for big companies to move to new releases.  As a case in point, think of Internet Explorer 6.  It&#8217;s an ancient browser but still widely used.  The last holdouts for IE6 tend to be corporations where IE6 is company policy.  The lesson for your software: you may need to support and interoperate with very old products and technologies.</p><h3>3. Everything is standardized</h3><p>Big corporations like to standardize their operations.  For software, this usually means that some part of the IT organization defines standard &#8220;builds&#8221; of operating systems.  The build locks down the operating system, the OS version, applications, and their configurations.  All new boxes are installed with a standard build.  In order to be included in the standard build, your software must have no required setup steps after installation. Your configuration files, for example, should be designed so that the same exact configuration can be used on multiple hosts.</p><h3>4. Prepare to integrate</h3><p>The IT infrastructure in every big company will have a number of systems your software may need to integrate with.  Possible candidates for integration could be identity management systems (Active Domain, LDAP, NIS+) , single sign-on systems, content management systems, CRM, and so on.  You must design your software so you can integrate with everything and anything that makes sense for your application domain.  If your software requires user accounts to be created and maintained separately, don&#8217;t expect a bank to buy it.</p><h3>5. Prepare to port</h3><p>The largest companies have huge global IT environments.  They have acquired other companies.  Semi-independent subsidiaries have been running their IT operations in different ways for years.  This means that there will almost always be a number of various operating systems in use throughout the organization.  There&#8217;s Windows on the desktops and maybe on some servers as well.  There is usually a substantial number of servers running some flavor of UNIX: AIX, HP-UX, Linux, or Solaris.  In the banking world, there will be AS/400 or z/OS mainframes, or both.  Rarely, there are some Macs in desktop use as well.</p><p>Depending on the nature of your software, you may need to support a number of platforms.  If you&#8217;re lucky, it&#8217;s only going to be a couple of different UNIX.  In the worst case, you have to port your code to Windows, all the UNIX, plus the mainframe as well.</p><h3>6. Prepare to release patches</h3><p>Due to the large deployments, standardized builds, and dependencies to other software, you will be hard pressed to deliver fixes to problems by offering the fixes in the latest version.  Usually there are policies which allow for a lightweight validation process for patches but require a larger project for a new release in fear of regressions (and rightfully so).  Prepare to deliver patches, or minimal changes in some other way, so your customers can get the fixes they need and only the fixes they need.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/making-me-hire-you/' rel='bookmark' title='Permanent Link: Inside Tips for Making Me Hire You'>Inside Tips for Making Me Hire You</a></li><li><a
href='https://hackerboss.com/platforms-come-with-a-culture/' rel='bookmark' title='Permanent Link: Platforms Come With a Culture'>Platforms Come With a Culture</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/tips-for-small-software-vendors-to-understand-enterprise-customers/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Night Time is the Right Time</title><link>https://hackerboss.com/night-time-is-the-right-time/</link> <comments>https://hackerboss.com/night-time-is-the-right-time/#comments</comments> <pubDate>Thu, 06 Aug 2009 20:56:51 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[motivation]]></category> <category><![CDATA[night]]></category> <category><![CDATA[Productivity]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=623</guid> <description><![CDATA[There’s clearly a pattern here. Good code happens at night. Night time is the right time… for coding.  Sometimes, for me, at least.No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/night-time-is-the-right-time/" title="Permanent link to Night Time is the Right Time"><img
class="post_image alignnone" src="http://hackerboss.com/wp/wp-content/uploads/pics/dude-lights.jpg" width="500" height="333" alt="Hacking at night." /></a></p><p><span
class="drop_cap">L</span>ooking back, I tend to do my most interesting programming at night. Writing the query optimizer for <a
href="http://hibase.cs.hut.fi">HiSQL</a> kept me up a couple of nights. The first versions of <a
href="http://laurikari.net/tre/">libtre</a> (a regex matching library with support for approximate matching) took a number of long evenings.   I wrote the first prototype for <a
href="http://www.ssh.com/support/documentation/online/ssh/admin-connectsecure/61/ssh-capture.html">transparent tunneling of TCP connections over SSH</a> for <a
href="http://www.ssh.com/products/automation/connectsecure/">SSH Tectia ConnectSecure</a> in the middle of the night.</p><p><strong>There&#8217;s clearly a pattern here.  Good code happens at night.</strong> Night time is the right time&#8230; for coding.   Sometimes, for me, at least.</p><p>The question is, why?   Am I so excited about the ideas, so beside myself with the anticipation of turning the idea into something real, that I cannot sleep?   Or is it that I simply need the peace and quiet in order to get into the zone?  Maybe when I&#8217;m <em>in</em> the zone I don&#8217;t want to stop, then loose track of time, and end up coding into the night?   All of the above?</p><p>Regardless of the reason, it does appear that I&#8217;m not <a
href="http://stackoverflow.com/questions/205499/when-do-you-prefer-to-code/205616">alone</a> <a
href="http://stackoverflow.com/questions/211234/best-time-of-day-to-code">with this</a>.</p><p>This makes me wonder if software companies should rethink some of their policies regarding working times.  <strong>Wouldn&#8217;t it make sense to allow doing the work in flexible pieces?</strong> Maybe spend the morning until lunch at the office, and do the rest at home in the evening?</p><p>Furthermore, there&#8217;s evidence that <a
href="http://en.wikipedia.org/wiki/Power_nap#Benefits">a short nap can significantly boost productivity</a>.   A 20-minute nap can make all the difference, apparently.  I certainly cannot get much thinking done in the early afternoon.  I tend to take care of some of my more rote, menial tasks during the groggy post-lunch time.   I&#8217;m a manager, so there&#8217;s plenty of that kind of work for me, alas.   But for a software developer, <strong>wouldn&#8217;t it make sense to take that 20-minute nap, and wake up fresh, instead of hours of half-witted monitor-staring?</strong></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/night-time-is-the-right-time/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>How to Find Bugs in Four Easy Steps</title><link>https://hackerboss.com/how-to-find-bugs-in-four-easy-steps/</link> <comments>https://hackerboss.com/how-to-find-bugs-in-four-easy-steps/#comments</comments> <pubDate>Mon, 03 Aug 2009 19:05:52 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Humor]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[debugging]]></category> <category><![CDATA[methodology]]></category> <category><![CDATA[Productivity]]></category> <category><![CDATA[trick]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=593</guid> <description><![CDATA[Step 1: Beg, borrow, steal, buy, fabricate or otherwise obtain a rubber duck (bathtub variety).No related posts.]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/how-to-find-bugs-in-four-easy-steps/" title="Permanent link to How to Find Bugs in Four Easy Steps"><img
class="post_image alignnone" src="http://hackerboss.com/wp/wp-content/uploads/2009/08/rubber-duck-debugging.jpg" width="280" height="214" alt="Going over some code with Mr. Duck. " /></a></p><p><a
href="http://lists.ethernal.org/oldarchives/cantlug-0211/msg00174.html">The Rubber Duck method of debugging</a> goes like this:</p><blockquote><ol><li>Beg, borrow, steal, buy, fabricate or otherwise obtain a rubber duck (bathtub variety).</li><li>Place rubber duck on desk and inform it you are just going to go over some code with it, if that&#8217;s all right.</li><li>Explain to the duck what you code is supposed to do, and then go into detail and explain things line by line.</li><li>At some point you will tell the duck what you are doing next and then realise that that is not in fact what you are actually doing.  The duck will sit there serenely, happy in the knowledge that it has helped you on your way.</li></ol></blockquote><p>This works amazingly well.  There&#8217;s a whole section in the book The Pragmatic Programmer about it. Also, The Practice of Programming describes the close relative, the Teddy Bear method of Filtering Bug Reports:</p><blockquote><p>One university computer center kept a teddy bear near the help desk.  Students with mysterious bugs were required to explain them to the bear before they could speak to a human counsellor.</p></blockquote><p>You should definitely get these books if you&#8217;re interested in reading about insights similar to the rubber duck.  These books are full of great stuff, but especially The Pragmatic Programmer does an awesome job of explaining things such as the broken window theory, defensive programming, and the DRY principle.</p><table
border="0"><tbody><tr><td><a
href="http://www.amazon.co.uk/dp/020161622X?tag=hashedbits-20"><img
class="alignleft" title="The Pragmatic Programmer" src="http://ec1.images-amazon.com/images/P/020161622X.01._AA240_SCLZZZZZZZ_.jpg" alt="The Pragmatic Programmer" width="240" height="240" /></a></td><td><a
href="http://www.amazon.co.uk/dp/020161586X?tag=hashedbits-20"><img
class="alignright" title="The Practice of Programming" src="http://ecx.images-amazon.com/images/I/41DGMPF6FJL._SL500_AA240_.jpg" alt="The Pragmatic Programmer" width="240" height="240" /></a></td></tr></tbody></table><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/how-to-find-bugs-in-four-easy-steps/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Heuristics for Programming Language Design</title><link>https://hackerboss.com/heuristics-for-programming-language-design/</link> <comments>https://hackerboss.com/heuristics-for-programming-language-design/#comments</comments> <pubDate>Mon, 27 Jul 2009 18:06:00 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[design]]></category> <category><![CDATA[heuristics]]></category> <category><![CDATA[languages]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=575</guid> <description><![CDATA[These are ten general principles for programming language design. They are called “heuristics” because they are more in the nature of rules of thumb than specific usability guidelines. My apologies to Mr. Nielsen for messing with his stuff.Related posts:<ol><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/the-three-doors-of-type-systems/' rel='bookmark' title='Permanent Link: The Three Doors of Type Systems'>The Three Doors of Type Systems</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p><span
class="drop_cap">T</span>he primary purpose of the programming language is to make it easy for the programmer to communicate to <i>other humans</i> what the program does.  Incidentally, the programs are also interpreted by the computer.</p><p>Jakob Nielsen, a famous usability guru, has defined <a
href="http://www.useit.com/papers/heuristic/heuristic_list.html">ten general principles for user interface design</a>.  What follows are Nielsen&#8217;s principles applied to programming language design.</p><p>When reading this, bear in mind that a programming language is much more than just a language manual and a compiler.  The whole development environment and ecosystem of libraries are as much part of the programming language as the syntax and semantics of the core language.  Even the online community of programmers can be thought of part of the language.  So when I&#8217;m talking about &#8220;programming languages&#8221;, I usually refer to the whole experience, not just the bare language.</p><p>These are ten general principles for programming language design.  They are called &#8220;heuristics&#8221; because they are more in the nature of rules of thumb than specific usability guidelines.  Some of these heuristics are clearly applicable to the design of the core language, some to the IDE, others perhaps to standard language libraries.</p><p>My apologies to Mr. Nielsen for messing with his stuff.</p><h3>Visibility of system status</h3><p>The system should always keep the programmer informed about what is going on, through appropriate feedback within reasonable time.</p><h3>Match between system and the real world</h3><p>The system should speak the programmers&#8217; language, with words, phrases and concepts familiar to the programmer, rather than programming language theory-oriented terms.  Follow real-world conventions, making the system behave in a natural and logical order.</p><h3>Programmer control and freedom</h3><p>Real-world system resources are often unavailable or fail.  Program code using these will need an effortless &#8220;emergency exit&#8221; to leave the unwanted state without having to clutter the code with error handling.</p><h3>Consistency and standards</h3><p>Programmers should not have to wonder whether different syntaxes, contexts, or names mean the same thing.  Follow platform conventions.</p><h3>Error prevention</h3><p>Even better than good error codes is a careful design which prevents a problem from occurring in the first place.  Either eliminate error-prone conditions or check for them and present programmers with information on the different ways their code may fail.</p><h3>Recognition rather than recall</h3><p>Minimize the programmer&#8217;s memory load by making objects, actions, and options visible.  The programmer should not have to remember information from one part of the program to another.  Instructions for use of the system should be visible or easily retrievable whenever appropriate.</p><h3>Flexibility and efficiency of use</h3><p>Accelerators &#8211; unseen by the novice programmer &#8211; may often speed up the interaction for the expert user such that the system can cater to both inexperienced and experienced users.  Allow programmers to tailor frequent actions.</p><h3>Aesthetic and minimalist design</h3><p>Functions should not require arguments which are irrelevant or rarely needed.  Every extra unit of information in a parameter list competes with the relevant units of information and diminishes their relative visibility.</p><h3>Help programmers recognize, diagnose, and recover from errors</h3><p>Error and warning messages should be expressed in plain language (no codes), precisely indicate the problem, and constructively suggest a solution.</p><h3>Help and documentation</h3><p>Even though it is better if the system can be used without documentation, it may be necessary to provide help and documentation.  Any such information should be easy to search, focused on the user&#8217;s task, list concrete steps to be carried out, and not be too large.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li><li><a
href='https://hackerboss.com/the-three-doors-of-type-systems/' rel='bookmark' title='Permanent Link: The Three Doors of Type Systems'>The Three Doors of Type Systems</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/heuristics-for-programming-language-design/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</title><link>https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/</link> <comments>https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/#comments</comments> <pubDate>Mon, 20 Jul 2009 21:26:20 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[concurrency]]></category> <category><![CDATA[cow]]></category> <category><![CDATA[languages]]></category> <category><![CDATA[stm]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=533</guid> <description><![CDATA[You can easily build databases from whatever data structures are the most natural for your application. You can kiss all that RDBMS crap goodbye. No more shoehorning your data into an awkward tables-and-columns format, no more marshalling and demarshalling your data to whatever data types the database happens to support, and no more SQL.Related posts:<ol><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p>Read the <a
href="http://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/">intro</a>, <a
href="http://hackerboss.com/copy-on-write-101-part-1-what-is-it/">part 1</a>, and <a
href="http://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/">part 2</a> first.</p><p><span
class="drop_cap">T</span>his is a description of a fictitious programming language.  It is purposefully vague here and there.  Nevertheless, I don&#8217;t think I&#8217;m exactly reaching for the moon here.  Or perhaps I am, you tell me.  Point is, this is just fantastic, wholesome, and thoroughly enjoyable academic masturbation.  Shall we begin?</p><p>We need a name for the language, so let&#8217;s call it Shark.</p><div
class="bigquote">&#8220;As far non-existent programming languages go, Shark is the dog&#8217;s bollocks.&#8221;</div><p>Shark uses a purely copy-on-write data model.  By this I mean that, <em>as far as the programmer can tell</em>, values are never modified.  Once you create an integer, a string, a list, or a forest of suffix trees containing all the words in the Klingon language, you cannot modify it.</p><p>Shark is, of course, garbage collected.  Shark is also strongly typed, supports both static and dynamic typing, and has type inference.  You have your lambdas, partial evaluation, algebraic data types, pattern matching, a fantastic module system, and a clean and concise but not too unfamiliar syntax.  As far non-existent programming languages go, Shark is the <a
href="http://www.youtube.com/watch?v=0rYT0YvQ3hs">dog&#8217;s bollocks</a>.</p><p>Shark has lightweight threads.  Spawning new threads is almost free (only a handful of instructions on the CPU).  Threads are automatically distributed to your CPUs and cores.  Just to be absolutely crystal clear, Shark threads are <em>not</em> the same as operating system threads such as POSIX threads.  Shark threads communicate exclusively through message passing.  Each thread has a message queue from which it can read incoming messages when it wants to.</p><p><img
class="alignleft" title="Shark eats LINQ to SQL for breakfast." src="http://www.wildanimalfightclub.com/Portals/41405/images//Great-White-shark-South-Australia.jpg" alt="Shark eats LINQ to SQL for breakfast." width="274" height="205" /></p><p>There are no locks, condition variables, and no modifiable shared resources.  When threads share data they do it explicitly, in a controlled fashion, for selected data only.  Shark comes with built-in support for software transactional memory.  You can easily build databases from whatever data structures are the most natural for your application.  You can kiss all that RDBMS crap goodbye.  No more shoehorning your data into an awkward tables-and-columns format, no more marshalling and demarshalling your data to whatever data types the database happens to support, and no more SQL.</p><p>The natural model to maintain state in Shark programs is to have a single thread govern the evolution of that state.  The thread can then pass around copies of the state, maybe receive operations from other threads to update the state, and so on.  Typically the state takes the form of an STM database which can be updated transactionally from multiple threads concurrently.</p><p>Just one more thing.  Shark STM databases can optionally be stored on disk.  It&#8217;s so efficient that you can run tens of thousands of transactions per second and have them checkpointed to disk a dozen times per second.  This gets you the Durability in ACID, the one piece that regular STM normally doesn&#8217;t provide.  Even though the entire database must reside in main memory, you&#8217;ll need to have a pretty big database for that to become a problem.  RAM is insanely cheap nowadays.</p><p>So, that&#8217;s my hallucinogen-induced (not really) vision of the perfect solution for concurrent programming and database management.  Yeah, I know creating your own programming language is basically never the right thing to do.  In my defense, at least I haven&#8217;t implement Shark.  Not yet, at least&#8230;</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</title><link>https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/</link> <comments>https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/#comments</comments> <pubDate>Sun, 21 Jun 2009 22:35:16 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[complexity]]></category> <category><![CDATA[concurrency]]></category> <category><![CDATA[cow]]></category> <category><![CDATA[languages]]></category> <category><![CDATA[optimization]]></category> <category><![CDATA[stm]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=473</guid> <description><![CDATA[Software transactional memory is like your own private in-memory database.  If you haven’t heard of it before, I strongly suggest you to find out soon.  Software transactional memory provides everything an ACID database would without the durability part...Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p>In my last post I gave a <a
href="http://hackerboss.com/copy-on-write-101-part-1-what-is-it/">quick introduction to copy-on-write data structures</a>; make sure to read that first.   It all started with <a
href="http://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/">a vague assertion on how copy-on-write is supposed to be a great advance for concurrent programming</a>.   I was met with a lot of blank stares, and possibly embarrassed silence.  So, instead of merely waving you off, dear reader, as ignorant, I&#8217;ll try to educate you on the marvels of copy-on-write (COW) data structures.</p><p>In this part I&#8217;ll show some areas where COW data structures have proven to be useful, and talk about some practical considerations when implementing COW data structures in real life.</p><h2>Some applications</h2><p><img
class="size-full wp-image-509 alignright" title="An inductor (can be used together with a capacitor to match impedance)." src="http://hackerboss.com/wp/wp-content/uploads/2009/06/inductor.jpg" alt="An inductor (can be used together with a capacitor to match impedance)." width="270" height="285" /></p><h3>Undo</h3><p>Often your programs allow the users to manipulate some data: text documents, configuration settings, diagrams, vegetarian pizza menus&#8230; any number of things.   If the manipulated data is stored in a COW data structure, implementing unlimited undo functionality becomes almost free.</p><p>All you need to do is put the different versions of the data on a list.  Structure sharing makes sure you don&#8217;t waste too much memory for the old versions.   Accessing the old versions takes no extra effort, they&#8217;re just right there.</p><h3>Optimization</h3><p>This appears to be what most people think copy-on-write is for.   It is correct that COW can be a useful optimization strategy, but it is by no means the only useful application.</p><p>Anyway, as an example, say you have a long string and you want to append something to the string.   In many programming languages strings cannot be modified like that efficiently; the space for the string has been preallocated and extending the string may require you to allocate a new larger memory area and move the data there.  A COW string typically allows for cutting and pasting pieces to anywhere in the string without having to copy everything.</p><h3>Software transactional memory</h3><p>This is a big one.  <a
href="http://en.wikipedia.org/wiki/Software_transactional_memory">Software transactional memory</a> is like your own private in-memory database.  If you haven&#8217;t heard of it before, I strongly suggest you to find out soon.  Software transactional memory provides everything an ACID database would without the durability part, since you&#8217;re dealing with data structures in RAM after all.  A big advantage is zero <a
href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch">impedance mismatch</a>, among other things.  COW data structures are the natural way to implement software transactional memory.</p><h2>Practical considerations</h2><p>Automatic memory management (e.g. garbage collection) is a must-have to conveniently deal with COW data structures.  In fact,  I would make the same argument for almost any kind of programming, but it&#8217;s doubly true for COW.</p><p>Most of the data structures you&#8217;ll be dealing with are going to be some type of <a
href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">directed acyclic graphs</a> built of nodes linked to other nodes, plus possibly some of the &#8220;real&#8221; data you are storing along with the graph structure nodes.   You need to allocate the nodes separately and, because this is COW, you&#8217;ll be allocating <em>all the time</em>.   Allocating cells from a garbage collected heap is typically extremely fast, so it&#8217;s the perfect way to manage memory in the COW world.</p><p
style="text-align: center;"><img
class="size-full wp-image-514 aligncenter" title="An AMD Phenom CPU die, showing large areas covered by L1 and L2 caches." src="http://hackerboss.com/wp/wp-content/uploads/2009/06/phenom.jpg" alt="phenom" width="415" height="300" /></p><h3>Constant factors</h3><p>Often, you want to use a COW data structure because you need to keep <em>some</em> old versions around for a while.   But you don&#8217;t necessarily want to hang on to <em>every</em> version, so you may wonder if the performance hit of a COW data structure is getting too big.   In most cases, <a
href="http://www.codinghorror.com/blog/archives/000061.html">I wouldn&#8217;t worry about it very much</a>.</p><p>To update one node in a mutable tree, you start from the root node, then make your way to the node you&#8217;re looking for.  Once you&#8217;ve found that node, you just change it, in-place.   In a COW tree, you&#8217;ll need to trace back to to the root node and make copies of each node on the way back.</p><p>So the tree is traversed twice, once both ways, and that will take about twice the time, right?   It turns out that this is not the case on modern computers.   When it&#8217;s time to copy the path, the data you need is almost certainly already in the L1 cache so revisiting the nodes again takes almost no time at all.</p><p>Also, since we&#8217;re allocating memory for the new nodes from a garbage collected heap, allocating memory is<em> really fast</em> so that isn&#8217;t really going to make a big hit either.  For these reasons, the constant factor slowdown for a COW tree vs. a mutable tree can be quite small indeed.</p><h3>Asymptotic complexity</h3><p>It is <a
href="http://web.comlab.ox.ac.uk/people/Geraint.Jones/morehaste.html">a fact</a> that there are problems which take linear time in an imperative programming language but suffer an unavoidable <em>O(log n)</em> slowdown in a purely functional (and strict) language.   These cases seem to be rare in practice, though.   There are algorithms even for <a
href="http://books.google.fi/books?id=AQbhbphyOsoC&amp;pg=PA110&amp;lpg=PA110&amp;dq=Fully+Persistent+Arrays+for+Efficient+Incremental+Updates+and+Voluminous+Reads+(1992)&amp;source=bl&amp;ots=LNIFlIulkD&amp;sig=Ymvd3bGfjHEAH7jej6lvDrDnc_o&amp;hl=fi&amp;ei=nKA-SvTHNtLp-Qav0I3TDA&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=4">efficient copy-on-write arrays</a>.</p><p>Next: <a
href="http://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/">Copy-on-write 101 &#8211; Part 3: The sum of its parts</a> — how COW makes concurrent programming possible without your brain turning into pineapple custard.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Copy-On-Write 101 &#8211; Part 1: What Is It?</title><link>https://hackerboss.com/copy-on-write-101-part-1-what-is-it/</link> <comments>https://hackerboss.com/copy-on-write-101-part-1-what-is-it/#comments</comments> <pubDate>Sun, 07 Jun 2009 20:54:47 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[cow]]></category> <category><![CDATA[data structures]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=394</guid> <description><![CDATA[Once you have gone and created a binary tree, you can never ever change it.  Adding an arrow from 21 to 34 is not allowed, no sir, over here in the wacky world of copy-on-write you have to create a modified copy instead of actually modifying anything.Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p>My previous post was about <a
href="http://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/"> how I think copy-on-write is the future of concurrent programming</a>.  The next day, I was trying to explain the idea to a couple of colleagues but got just blank stares in return.  It struck me that most programmers don&#8217;t really know much about copy-on-write techniques, how (or even <em>if</em>) they work, and what kinds of problems they&#8217;re best suited for.   So, I&#8217;ve decided to write a small series of posts on this subject.   In this first post, I&#8217;ll explain the basic idea of copy-on-write data structures.</p><p>Traditional data structures are <em>mutable</em>.   Let&#8217;s look at a simple <a
href="http://en.wikipedia.org/wiki/Binary_search_tree">binary search tree</a>, for example:</p><p><img
class="size-full wp-image-439 alignnone" title="A binary search tree" src="http://hackerboss.com/wp/wp-content/uploads/2009/06/binary-tree-1.png" alt="A binary search tree" width="220" height="199" /></p><p>Each node in the tree consists of a value (the number) and zero, one, or two arrows pointing to other nodes.  Say you want to add a new node, a 34, in this tree.   That&#8217;s easy, we just draw the new node in the right place:</p><p><img
class="alignnone size-full wp-image-441" title="A binary search tree" src="http://hackerboss.com/wp/wp-content/uploads/2009/06/binary-tree-2.png" alt="A binary search tree" width="252" height="199" /></p><p>Note that the tree is now <em>changed</em>.   We had to update node 21 to point to node 34 in addition to 13.  The original tree for all practical purposes <em>does not exist anymore</em>.   Well, OK, it does on this page right here, but you get the point.  At any one time, there is exactly one version of the tree in existence in your program.</p><p>A copy-on-write data structure, on the other hand, is <em>immutable</em>.   Once you have gone and created a binary tree, you can never ever change it.  Adding an arrow from 21 to 34 is not allowed, no sir, over here in the wacky world of copy-on-write you have to create a modified copy instead of actually modifying anything.</p><p>If having to copy the entire tree seems a little bit ridiculous to you, that&#8217;s because it probably is.   Typically, two trees are considered equal if they represent the same structure.   Hence, it does not matter where the nodes of the tree are stored in memory, for example.  In fact, in many programming languages there is even no way to distinguish between two copies of otherwise identical pieces of data.   With this in mind, we can <em>share structure</em> instead of taking a full copy:</p><p><img
class="alignnone size-full wp-image-446" title="Binary search trees" src="http://hackerboss.com/wp/wp-content/uploads/2009/06/binary-tree-3.png" alt="Binary search trees" width="382" height="201" /></p><p>Here we have both the old tree (without the 34) and the new tree (including the 34).  An application will be looking at this data through a window that is the programming language, and all it sees are the two completely separate versions of the tree.  They happen to share some structure, but that arguably does not matter much to the application.</p><p>In general, if you&#8217;re updating one node, taking a modified copy of a tree will require copying only the path from the root node of the tree to the affected node.  And that&#8217;s how copy-on-write trees work: path copying.  Tah-dah!</p><p>It is not immediately clear if a structure-sharing copy-on-write counterpart can be created for all mutable data structures.  All tree-like structures can clearly be handled with the path copying trick.  Other structures, such as <a
href="http://en.wikipedia.org/wiki/Queue_(data_structure)">queues,</a> seem harder, perhaps impossible at first glance.</p><p><a
href="http://www.amazon.com/dp/0521663504?tag=hashedbits-20"><img
class="alignleft" title="Purely Functional Data Structures" src="http://ecx.images-amazon.com/images/I/410CKVZM2EL.jpg" alt="Purely Functional Data Structures" width="308" height="475" /></a>Luckily, it turns out that smart people have already designed efficient copy-on-write versions of queues and many other important data structures; there&#8217;s a great book on the subject by Chris Okasaki called <a
href="http://www.amazon.com/dp/0521663504?tag=hashedbits-20">Purely Functional Data Structures</a>.   It&#8217;s by far the best resource on copy-on-write data structures that I&#8217;ve encountered.</p><p>Note how I prefer to say &#8220;copy-on-write&#8221; instead of &#8220;purely functional&#8221;.   The term &#8220;functional&#8221; is just way too overloaded and carries a lot of negative connotations in the minds of working programmers who don&#8217;t much care for many of the things that functional programming is often associated with.</p><p>The use of copy-on-write data structures is not limited to functional programming, so let&#8217;s not marry the two by calling them with the same name.</p><p>Copy-on-write data structures are also sometimes called &#8220;persistent&#8221; data structures, because the old versions are preserved; they &#8220;persist&#8221; in memory.  In practice, this is easily confused with persistent storage (e.g. disk), so I avoid using that name as well.</p><p>Next: <a
href="http://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/">Copy-on-write 101 &#8211; Part 2: Putting it to use</a></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/' rel='bookmark' title='Permanent Link: I Have Seen the Future, and It is Copy-On-Write'>I Have Seen the Future, and It is Copy-On-Write</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/copy-on-write-101-part-1-what-is-it/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>I Have Seen the Future, and It is Copy-On-Write</title><link>https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/</link> <comments>https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/#comments</comments> <pubDate>Wed, 27 May 2009 20:46:37 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Innovation]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[concurrency]]></category> <category><![CDATA[cow]]></category> <category><![CDATA[languages]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=365</guid> <description><![CDATA[The code was elegant, easy to understand, and ridiculously efficient.  There wasn't a single lock or critical section in the entire system.  Just threads, message passing, and copy-on-write data structures.  Beautiful.Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p><a
href="http://en.wikipedia.org/wiki/Copy-on-write">Copy-on-write</a> is a similar advance for concurrent programming as garbage collection was for memory management.</p><p>I became a copy-on-write believer at around the turn of the millennium when I was working for the <a
href="http://hibase.cs.hut.fi/">HiBase</a> project as a research assistant.  Among other things, I implemented an in-memory SQL database server in Shines, our prototype programming language, which used a strictly copy-on-write memory model.  We employed an <a
href="http://en.wikipedia.org/wiki/Optimistic_concurrency_control">optimistic concurrency control</a> algorithm to resolve possible conflicts for database transactions run in parallel.  The code was elegant, easy to understand, and ridiculously efficient.  There wasn&#8217;t a single lock or critical section in the entire system.  Just threads, message passing, and copy-on-write data structures.  Beautiful.</p><p><a
href="http://davidvmoore.com/?p=108"><img
class="alignright size-full wp-image-380" title="Close Threads" src="http://davidvmoore.com/wp-content/gallery/traditional/close-threads.jpg" alt="Close Threads" width="280" height="352" /></a>John McCarthy invented garbage collection for Lisp in 1959.  It took almost 40 years for garbage collection to finally hit the mainstream programming consciousness with Java.  I&#8217;m not exactly sure when the copy-on-write data model was invented, but based on the <a
href="http://en.wikipedia.org/wiki/Functional_programming">Wikipedia page on functional programming</a> I&#8217;m going to place it somewhere in the 1970s.  It would be about time for copy-on-write to hit mainstream now, but I don&#8217;t see that happening.  What&#8217;s wrong?</p><p>The <a
href="http://www.erlang.org/faq/faq.html">Erlang</a> guys have touted the copy-on-write model to be the True Way to do concurrent programming for years.  But Erlang isn&#8217;t enjoying much success in the mainstream.  I suspect this is to do with the <a
href="http://www.defmacro.org/ramblings/fp.html">academic stigma</a> that goes with functional programming and the <a
href="http://humani.st/why-make-erlang-a-functional-language/">unusual syntax inherited from Prolog</a>.</p><p>Nowadays, copy-on-write techniques are growing increasingly popular also outside the confines of RAM.  In the past ten or so years, a number of file systems have popped up which use a copy-on-write data model to implement snapshotting, for example.  I find <a
href="http://all-unix.blogspot.com/2007/03/zfs-cow-and-relate-features.html">ZFS</a> to be the most promising of these.  <a
href="http://blogs.sun.com/bonwick/entry/raid_z">RAID-Z</a> is just super cool.  But let&#8217;s get back to programming languages.</p><p>I believe the concurrent programming language for the mainstream will have the copy-on-write data model, threads with message passing, a familiar syntax, plus a big ecosystem of libraries and tools.  Most importantly, though, the language won&#8217;t called a &#8220;functional&#8221; language, even though it might in reality be awfully close to being one.  I wonder when this language will appear.  Or does it already exist?</p><p>Next: <a
href="http://hackerboss.com/copy-on-write-101-part-1-what-is-it/">Copy-on-write 101 &#8211; Part 1: What is it?</a></p><p>Related posts:<ol><li><a
href='https://hackerboss.com/copy-on-write-101-part-3-the-sum-of-its-parts/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts'>Copy-On-Write 101 &#8211; Part 3: The Sum of Its Parts</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-2-putting-it-to-use/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 2: Putting It to Use'>Copy-On-Write 101 &#8211; Part 2: Putting It to Use</a></li><li><a
href='https://hackerboss.com/copy-on-write-101-part-1-what-is-it/' rel='bookmark' title='Permanent Link: Copy-On-Write 101 &#8211; Part 1: What Is It?'>Copy-On-Write 101 &#8211; Part 1: What Is It?</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/i-have-seen-the-future-and-it-is-copy-on-write/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>The Shell is Like a Dishwasher</title><link>https://hackerboss.com/the-shell-is-like-a-dishwasher/</link> <comments>https://hackerboss.com/the-shell-is-like-a-dishwasher/#comments</comments> <pubDate>Wed, 20 May 2009 21:50:02 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Productivity]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[powershell]]></category> <category><![CDATA[python]]></category> <category><![CDATA[shell]]></category> <category><![CDATA[tools]]></category><guid
isPermaLink="false">http://hackerboss.com/?p=352</guid> <description><![CDATA[With the shell, it's "sTABnTABkTABsTABn" and you're done in a fraction of the time.  Why can't you do that in the file browser GUI?No related posts.]]></description> <content:encoded><![CDATA[<p></p><p>Sometimes I&#8217;m just so glad I know shell.  I mean things like</p><div
class="wp_syntax"><div
class="code"><pre class="bash"><span style="color: #c20cb9; font-weight: bold;">find</span> . <span style="color: #660033;">-type</span> f <span style="color: #660033;">-print0</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">100</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-1sk</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">-10</span></pre></div></div><p>For the uninitiated: the above command lists the ten largest files under the current working directory (including subdirectories).  How do the Windows power users do stuff like this?  PowerShell?  Python programs?  Can you even write one-liners in Python?</p><p>On a related note, it always pains me to watch people browse to a file in a file manager GUI.  You click through a bunch of folders and stare at each list of file names for a second before finding the right one, click on it, and by the time you&#8217;ve found your file the coffee&#8217;s gone cold.  With the shell, it&#8217;s &#8220;sTABnTABkTABsTABn&#8221; and you&#8217;re done in a fraction of the time.  Hot coffee.  Why can&#8217;t you do that in the file browser GUI?</p><p>The shell is like a dishwasher.  When I was a just poor undergrad CS student living off macaroni and ketchup &#8220;borrowed&#8221; from my roommate, I couldn&#8217;t afford a dishwasher.  There were more important things to spend money on, such as beer, science fiction, and macaroni.  At the time, washing dishes the old-fashioned way didn&#8217;t seem so bad.  In fact, I coped without a dishwasher for a long time after I would have been able to just buy one.  Now I wouldn&#8217;t dream of doing all my dishes manually.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-shell-is-like-a-dishwasher/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>The Golden Rule of Unit Testing</title><link>https://hackerboss.com/the-golden-rule-of-unit-testing/</link> <comments>https://hackerboss.com/the-golden-rule-of-unit-testing/#comments</comments> <pubDate>Tue, 12 May 2009 12:25:14 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Programming]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[design]]></category> <category><![CDATA[unit testing]]></category><guid
isPermaLink="false">http://laurikari.net/ville/?p=71</guid> <description><![CDATA[Harry has to make a few adjustments to the code; maybe he splits one function into two and replaces another function with new code.  He makes little whimpering noises as he deletes the now defunct tests for the old code.  He curses under his breath when he writes the new test drivers and stubs for the new code.Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol>]]></description> <content:encoded><![CDATA[<p></p><p><span
class="drop_cap">F</span>rom the Wikipedia article on <a
href="http://en.wikipedia.org/wiki/Unit_testing">unit testing</a>:</p><blockquote><p>&#8220;In computer programming, unit testing is a software verification and validation method where the programmer gains confidence that individual units of source code are fit for use. A unit is the smallest testable part of an application. In procedural programming a unit may be an individual program, function, procedure, etc., while in object-oriented programming, the smallest unit is a method, which may belong to a base/super class, abstract class or derived/child class.&#8221;</p></blockquote><p>If you take this definition of unit testing literally<strong> you are going to be testing exactly the wrong things.</strong></p><p>As an example, let&#8217;s assume we have a piece of code which is responsible for parsing some XML strings into data structures.  This isn&#8217;t arbitrary XML, the strings are all of this form:</p><pre>&lt;user&gt;
  &lt;id&gt;evalua&lt;/name&gt;
  &lt;name&gt;Eva Lu Ator&lt;/name&gt;
  &lt;message&gt;Anything in parentheses can be left out.&lt;/message&gt;
&lt;/user&gt;</pre><p>The result from parsing should be a record in memory with the id, name, and message all parsed out nicely.  Let&#8217;s further assume that this code is implemented, foolishly, using regular expressions, because the person who implemented it thought that using an actual XML parser would be overkill for such a simple task. Sigh. At least the code is all in it&#8217;s own module with a clear signature:</p><pre>structure Parser :&gt; signature
   type result = {id : string, name : string, message: string}
   val parse : string -&gt; result
end = struct
   &lt;imagine a barrel full of hairy regex matching code here&gt;
end</pre><p>(That&#8217;s Standard ML, you insensitive clod.)</p><p>The final assumption is that the person who wrote this code, let&#8217;s call him Harry, had heard that unit testing is a good thing, and had decided to write some tests.  Our hapless Harry sought out the Wikipedia article to double check what unit tests actually are and proceeded to write tests for each and every function, plus lots of stubs so that he could successfully tests each function in perfect isolation.  The amount of test code Harry has written is about three times the amount of his hairy regex matching code.</p><p><img
class="alignright" src="http://laurikari.net/ville/corridor.jpg" alt="" width="280" height="414" />Harry&#8217;s code works fine, until the first XML string with a multiline message comes up.  It wasn&#8217;t in the original requirements, so Harry didn&#8217;t originally add support for it because he had also read <a
href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It">You Ain&#8217;t Gonna Need It</a>.  Now he has to make a few adjustments to the code; maybe he splits one function into two and replaces another function with new code.  He makes little whimpering noises as he deletes the now defunct tests for the old code.  He curses under his breath when he writes the new test drivers and stubs for the new code.  But he manages to get it all done, and the code goes into production.</p><p>The holiday season arrives, and Harry flies off to a long-awaited vacation in Thailand.  While Harry is sipping piña coladas at the pool bar, his colleague, Ethan, gets an urgent bug to fix.  It turns out someone tried to put the &#8216;&lt;&#8217; and &#8216;&gt;&#8217; characters in the message, resulting in &amp;lt; and &amp;gt; in the XML, and Harry&#8217;s XML parser doesn&#8217;t handle them at all.  Ethan stares at Harry&#8217;s code for a while, deletes everything except the module signature, and writes some code to call a <em>real</em> XML parser and picks the needed parts straight from the DOM tree.</p><p>He writes a test program which parses example XML snippets and checks the results against known correct results.  He writes another test where the XML parser is a stub which fails in random ways (returns bad DOM trees, throws exceptions, etc.) to ensure his code can handle those situations.  Confetti starts streaming from the air conditioning vents, the birds outside burst into song, and a team of furiously cheerful tap-dancers dance along the corridors, joined by the office staff, all celebrating Ethan&#8217;s genius.</p><p>What did we learn from all this?  For one thing, unit tests won&#8217;t protect you against incompetent design. Second, blindly following rules will probably just get you in trouble.  Most importantly, <strong>unit tests make the code rigid. </strong>It makes little sense to write heaps of testing code against interfaces which will be changed soon.  Harry spent a lot of time rewriting test code when he had to add features to his parser.  Even though I just said that you shouldn&#8217;t be just following rules, I will nevertheless introduce <em>the golden rule of unit testing:</em></p><p
style="font-weight: bold; font-size: 120%; text-align: center">Test against interfaces which are not likely to change.</p><p>When the eventual refactoring is done, chances are that you&#8217;ll want to preserve <em>some</em> interface.  In Ethan&#8217;s case, he wasn&#8217;t so much refactoring but rewriting, but the module interface stayed the same.  Tests using only that module interface will help Ethan to test his new code.  Glass box tests designed for a particular implementation of the interface are not going to be helpful for Ethan.</p><p>If you&#8217;re writing software to go in a robotic spacecraft and you&#8217;re not exactly going to maintain and enhance that software after the launch because, to put it bluntly, you&#8217;d probably screw up and cause the $500m tin can to fly into the sun&#8230; In that kind of code <em>everything</em> can be unit tested, because <em>nothing</em> is going to be changed anyway, and it&#8217;s going to be worth it to gain a 0.1% improvement in the likelihood of catastrophic failure.  But in your regular software product which evolves all the time, along with the requirements, you&#8217;ll be wise to follow the golden rule and write tests only against those interfaces which don&#8217;t hopefully change all that often.</p><p>Oh, and please don&#8217;t ever parse XML using a heap of hairy regex code.</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/the-essence-of-lambda/' rel='bookmark' title='Permanent Link: The Essence of Lambda'>The Essence of Lambda</a></li><li><a
href='https://hackerboss.com/programming-problems-in-disguise/' rel='bookmark' title='Permanent Link: Programming Problems in Disguise'>Programming Problems in Disguise</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/the-golden-rule-of-unit-testing/feed/</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>A Little Known Way to Learn Touch Typing</title><link>https://hackerboss.com/how-i-learned-to-type/</link> <comments>https://hackerboss.com/how-i-learned-to-type/#comments</comments> <pubDate>Tue, 05 May 2009 20:18:15 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Productivity]]></category> <category><![CDATA[keyboards]]></category> <category><![CDATA[trick]]></category> <category><![CDATA[typing]]></category><guid
isPermaLink="false">http://laurikari.net/ville/?p=201</guid> <description><![CDATA[At some point, it dawned on me that I would have to start from scratch: I would have to learn to type with a non-qwerty keyboard layout.  My old skills would be useless on the new layout, so I would be forced to relearn.Related posts:<ol><li><a
href='https://hackerboss.com/a-developers-most-important-interface/' rel='bookmark' title='Permanent Link: A Developer&#8217;s Most Important Interface'>A Developer&#8217;s Most Important Interface</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a
class="post_image_link" href="https://hackerboss.com/how-i-learned-to-type/" title="Permanent link to A Little Known Way to Learn Touch Typing"><img
class="post_image alignnone" src="http://farm1.static.flickr.com/2/1585255_20d41d3bb1.jpg" width="499" height="376" alt="Post image for A Little Known Way to Learn Touch Typing" /></a></p><p>I&#8217;m constantly amazed at people who work with a computer every day, several hours per day, much of it typing in text, <em>but don&#8217;t know how to type</em>.  You&#8217;ve seen it: hands happily waving above the keyboard, twin index fingers scanning the rows of plastic keys, sometimes pecking at one; head bowed down, eyes fixed at the keyboard only to occasionally glance up at the screen to check the results.</p><p>Of course, I&#8217;m <a
href="http://www.codinghorror.com/blog/archives/001188.html">not the only one</a> to <a
href="http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html">have observed this</a>.</p><p>I was an OK typist already as a kid.  I remember taking a typing class, in the ninth grade I think, and scoring a straight A without even trying (or a 10 actually, the Finnish school grade system goes from 4 to 10).  My friends also marveled at my typing speed.  Regardless of this, I had bad typing habits.  For one thing, I was looking at the keyboard a lot.   Then at high school I got a new friend who was, to my great frustration,  even faster than me.  He knew touch typing.  I didn&#8217;t even know what the little raised dots on F and J were for.</p><p>During the first year at the university I decided to finally do something about my typing.  Unlearning my old typing method turned out to be really hard.  I would always just fall back to my old ways, because that&#8217;s what I had been doing for ten years, and it was just so much easier.    At some point, it dawned on me that I would have to start from scratch: I would have to learn to type with a non-qwerty keyboard layout.  My old skills would be useless on the new layout, so I would be <em>forced</em> to relearn.</p><p>At the time, most of the writing I did was either in Finnish or program code, so Dvorak didn&#8217;t seem like an optimal choice.  If I would have to learn a whole new layout, why not make something that would be perfect for me?  So, I wrote a small program which captured all my key presses and kept it running for a week or so.  Then I wrote a program which analyzed all the data, gathered the most common chords of two and three letters, and arranged they keys on the keyboard in an optimal way.</p><p>This is what my program made for me:</p><p><img
class="alignnone size-full wp-image-254" title="keyboard-detail-qhprjz" src="http://laurikari.net/ville/wp/wp-content/uploads/2009/05/keyboard-detail-qhprjz.jpg" alt="keyboard-detail-qhprjz" width="560" height="151" /></p><p>Changing the keyboard layout turned out to work wonderfully.  I couldn&#8217;t fall back to my old qwerty skills anymore, and started making real progress with touch typing.  Within a couple of weeks, I was up to my old typing speed.  After a couple of months I was already faster.</p><p>I still use this layout.</p><p>Nowadays I can easily reach 85-90 words per minute cold, typing in unfamiliar English text.  In my first language, which is Finnish, I&#8217;m probably somewhat faster.  The fun part is that I have a keyboard layout nobody else in the known universe can use.  It&#8217;s kinda fun to let a coworker sit at my computer and watch them fumble.</p><p>How did you learn touch typing?  Or do you still look at your keyboard?</p><p>Related posts:<ol><li><a
href='https://hackerboss.com/a-developers-most-important-interface/' rel='bookmark' title='Permanent Link: A Developer&#8217;s Most Important Interface'>A Developer&#8217;s Most Important Interface</a></li><li><a
href='https://hackerboss.com/the-programming-high/' rel='bookmark' title='Permanent Link: The Programming High'>The Programming High</a></li></ol></p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/how-i-learned-to-type/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>You Don&#8217;t Need a Deadline</title><link>https://hackerboss.com/you-dont-need-a-deadline/</link> <comments>https://hackerboss.com/you-dont-need-a-deadline/#comments</comments> <pubDate>Tue, 28 Apr 2009 17:26:03 +0000</pubDate> <dc:creator>Ville Laurikari</dc:creator> <category><![CDATA[Management]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[deadline]]></category> <category><![CDATA[prioritization]]></category> <category><![CDATA[Productivity]]></category> <category><![CDATA[project]]></category> <category><![CDATA[project management]]></category><guid
isPermaLink="false">http://laurikari.net/ville/?p=195</guid> <description><![CDATA[That's the holy trinity of project parameters: resources, scope, and schedule.  And suddenly, they're all more or less locked down.  The team, the features, the deadline.  One is based on vague ideas and another is derived from them.  Sounds good to me, now let's get to work!No related posts.]]></description> <content:encoded><![CDATA[<p></p><h2>Vague ideas</h2><p>In the beginning there are vague ideas, manifested as cubes of air floating around in the office, of what the finished product should do and what it should look like.</p><div
id="attachment_224" class="wp-caption alignleft" style="width: 280px"> <img
class="size-full wp-image-224" src="http://laurikari.net/ville/wp/wp-content/uploads/2009/04/vague-renoir.jpg" alt="Renoir - La Vague" width="280" height="210" /><p
class="wp-caption-text">Renoir: La Vague</p></div><p>Actually, that&#8217;s not correct.  In fact, if you were to ask anyone who has been sitting in the meetings mulling over the project scope, they would probably tell you that they have a pretty good idea of what it&#8217;ll look like. Granted, some people will say that just to avoid having to go to <em>another</em> meeting mulling over the project scope. But many genuinely think they have a pretty good idea; some parts they may have even imagined in moderate detail, covering maybe 5% of the entire thing,  and the rest they just blithely ignore.</p><p>Still, people <em>think</em> they have a pretty good idea, because the human mind is frighteningly good in filling in the gaps and creating this illusion that the gaps don&#8217;t even exist.  So, there&#8217;s not just one vague idea. <strong> There are several vague ideas and they are all different.</strong></p><h2>Whence come deadlines?</h2><p>Soon enough, it&#8217;s time to start sketching the project plan.  Based on the vague ideas someone comes up with guesstimates for how long it will take to turn each air cube into working code. In absence of detailed specs and explicit understanding, the guesstimates are of course wildly inaccurate.  And I don&#8217;t mean off by 10%, I mean crazy wrong, enough to make the corner of your left eye twitch embarrassingly at the project post-mortem.</p><p>Then there&#8217;s the meeting where the project is approved: the resources (manager-speak for developers) are granted, the scope agreed upon, and the deadline is set.  That&#8217;s the holy trinity of project parameters: resources, scope, and schedule.  And suddenly, they&#8217;re all more or less locked down.  The team, the features, the deadline.  One is based on vague ideas and another is derived from them.  Sounds good to me, now let&#8217;s get to work!</p><h2>Pressure</h2><p><img
class="alignright size-full wp-image-233" src="http://laurikari.net/ville/wp/wp-content/uploads/2009/04/pressure-gauge.png" alt="pressure-gauge" width="280" height="280" />Things appear to start off well.  Code is being written, features and tasks are being ticked off as complete, and the project seems to make good progress.</p><p>At some point, reality sinks in.  The requirements have become more clear, now that there are some builds that people can actually install and notice how it doesn&#8217;t do what they had imagined it would.  Features are added and removed.  GUIs are reworked.  Bug lists start to grow like the national debt.  The project manager grudgingly announces that the project is a bit late, but nothing we can&#8217;t handle, we&#8217;ll pick up the pace, start daily status update meetings, and work really hard.</p><p>The developers start to feel a little depressed.  The project is late, and they&#8217;re constantly being pressed to finish their tasks quicker and reworking parts they already though were fine. <strong> They start to make bad engineering decisions because there&#8217;s &#8220;no time&#8221; to do things properly. </strong> The second half of the project is a mad coding frenzy where good design flies out of the window, sadly waving bye-bye, never to be seen again.</p><h2>Go agile</h2><p>If anything like the above happens in your organization, you should<strong> take a close look at your business model and decide if keeping made up schedules is really the most important thing</strong>.  How much will you lose if you admit that the original schedule estimates were just guesswork, and move the schedule up a few weeks or months?  How much will you lose if half of the time your developers are stressed, depressed, and doing a poor job just to meet the schedule?</p><p>Software projects don&#8217;t complete quicker because there is a tight deadline and a lot of pressure to finish on time.  They complete quicker because the developers feel productive, positive, and in control, they have a good understanding of the priorities, the specifications were up-to-date and descriptive, and the project is <em>ahead</em> of schedule.</p><p>So, the next time you notice you&#8217;re setting a project deadline several months in the future, based on mostly on air cubes, stop right there.  Instead, specify the first iteration well and set an ETA for that, at most one month in the future.  It&#8217;s much easier to specify and estimate in small pieces.  When the first iteration is done, rinse and repeat until it&#8217;s all done.   That&#8217;s what agile development is all about.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>https://hackerboss.com/you-dont-need-a-deadline/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Database Caching using disk

Served from: hackerboss.com @ 2025-08-16 07:04:01 -->