<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
    <title>Lawrence Kesteloot's writings</title> 
    <link>http://www.teamten.com/lawrence/writings/</link> 
    <description>Lawrence Kesteloot's writings</description> 
    <language>en-us</language> 
    <copyright>Copyright 1993-2009 Lawrence Kesteloot.</copyright> 
    <managingEditor>Lawrence Kesteloot</managingEditor> 

    <item>
        <title><![CDATA[Jill]]></title>
        <link>http://www.teamten.com/lawrence/writings/jill.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/jill.html</guid>
        <pubDate>11 May 2011</pubDate>
        <description><![CDATA[

            <p class="very-first">Jill was my lab partner in 9th grade Earth
                Science class. She was pretty and had long blond hair with
                bangs and a large hard purse <em>and she programmed computers too</em>.</p>

            <p>At the time I was trying to calculate &pi; using what I now
                know is the Leibniz formula, and was explaining to her that
                it was converging very slowly, and she said that her program
                for calculating &pi; ran forever because &pi; is irrational.
                <em>She also was writing programs to calculate &pi;!</em></p>

            <p>But I didn&rsquo;t quite see how &pi;&rsquo;s irrationality would affect
                the program running forever, and she had a hard time explaining,
                so eventually she got impatient, grabbed a piece of paper,
                and started writing code. <em>She could write code from memory!</em>
                This is what she handed me:</p>

            <pre>
    10 INPUT &ldquo;What is the circumference? &rdquo;; c
    20 INPUT &ldquo;What is the diameter? &rdquo;; d
    30 PRINT c/d</pre>

            <p class="first">And that&rsquo;s the first time a girl broke my heart.</p>
        ]]></description>
    </item>

    <item>
        <title><![CDATA[Solar Plotter]]></title>
        <link>http://www.teamten.com/lawrence/writings/solar_plotter.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/solar_plotter.html</guid>
        <pubDate>11 Jul 2010</pubDate>
        <description><![CDATA[

            <p class="very-first">My friend <a href="http://monad.com/kurt/"
                    class="external">Kurt Schaefer</a> and I have built
                a <em>solar plotter</em>, which is a device that burns
                2-D patterns into wood by focusing the sun&rsquo;s light using
                a moving magnifying glass. Here&rsquo;s a video of it in action:</p>

            <object width="480" height="385" style="margin: 2em 0"><param name="movie" value="http://www.youtube.com/v/TNweEmtxtro&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/TNweEmtxtro&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>

            <p class="first">Kurt already had the 2-D table from a previous
                project that <a
                    href="http://monad.com/kurt/xy_table/XY_Table.html"
                    class="external">cut styrofoam using a hot wire</a>. We
                replaced the wire
                with a stand to hold the magnifying glass and added various bits
                so that the machine could face the sun.</p>

            <p>To burn a pattern, we bring it into Adobe Illustrator and
                use a plug-in that Kurt wrote to generate a file of
                <a href="http://en.wikipedia.org/wiki/G-code" class="external">G-codes</a>,
                which are industry-standard codes that control CNC (computer-controlled)
                machines. The file is imported into a program called <a
                    href="http://www.machsupport.com/"
                    class="external">Mach3</a>, which uses the parallel
                port to communicate with a board that controls the two stepper
                motors for the two axes.</p>

            <p>One interesting thing about a solar plotter is that the sun moves as
                you&rsquo;re making your plot. Even a simple circle that takes a minute to
                burn won&rsquo;t finish exactly where it started because the sun will have moved
                by then. A 10-minute burn (like the above) will have major errors in it.</p>

            <p>You can see the effect in this burn, which was one of our first:</p>

            <img style="display:block;margin: 2em 0" src="solar_plotter_pioneer.jpg"/>

            <p class="first">The &ldquo;O&rdquo; on the bottom starts at its upper-left, and that&rsquo;s
                where the discontinuity is. We burned the second &ldquo;E&rdquo; (lower-right) more
                slowly to verify that the problem was indeed the motion of the sun.
                The entire word shifts up because of this problem.</p>

            <p>I wrote a program that compensates for this. It reads a G-code file
                and some other data, such as your location on earth, time of
                year, time of day, and height of the magnifying glass above the
                wood, and generates a modified G-code file that adjusts for the
                sun&rsquo;s motion. It assumes that the board is perpendicular to the
                sun&rsquo;s rays when the burn starts. You have to run it just before
                you start the burn for the compensation to be correct.</p>

            <p>Here&rsquo;s the final picture of the fox that was being burned
                in the video above:</p>

            <img style="display:block;margin: 2em 0" src="solar_plotter_fox.jpg"/>

            <p class="first">I wrote another program that converts a raster image
                into a file of G-codes. It adjusts the speed of the plotter to
                generate different levels of gray, zig-zagging down the image.
                Naturally, I tested it with a photo of Bertrand Russell:</p>

            <img style="display:block; margin: 2em 0; float: left" src="solar_plotter_russell.jpg"/>
            <img style="display:block; margin: 2em 0 2em 2em; float: left" src="solar_plotter_small.jpg"/>

            <p class="first" style="clear: left">(The low-resolution version is what was
                actually converted. The high-resolution one would have taken
                too long.)</p>

            <p>Unfortunately this doesn&rsquo;t work
                well because the relationship between speed and blackness is very
                non-linear: once the wood burns at all, it&rsquo;s already quite black.</p>

            <p>One possible solution would be to install an iris on top of the
                magnifying glass. This would allow us to control the size of
                the spot being burned.  Kurt&rsquo;s already designed and built it:</p>

            <object width="480" height="385" style="margin: 2em 0"><param name="movie" value="http://www.youtube.com/v/jYcSwjvwe3E&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/jYcSwjvwe3E&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>

            <p class="first">We now have to hook it up to Mach3 somehow. One
                idea is to use the Z axis to encode aperture size, and use an
                Arduino board to convert stepper motor pulses into servo pulses
                to open and close the iris. (We would also close the iris when
                moving from object to object, which we do now by moving as fast
                as we can, hopefully faster than the wood can start to burn.)
                Another idea is to keep the iris small all the time and make
                darker patches using dithering in software.</p>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[Package Managers Hurt Open Source]]></title>
        <link>http://www.teamten.com/lawrence/writings/package_managers_hurt_open_source.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/package_managers_hurt_open_source.html</guid>
        <pubDate>21 Jun 2010</pubDate>
        <description><![CDATA[

            <p class="very-first">In the good old days, before fancy modern
                package managers like apt-get and yum, if you wanted an
                open-source program you had to download the source tarball,
                compile it, and install it. I kept the source around under my
                &ldquo;download&rdquo; directory. Several times I had an itch, and it was
                easy to go into the source, tweak something, and install it
                again. A few times I submitted the changes back to the
                maintainer of the program. (Vim&rsquo;s &ldquo;incsearch&rdquo; option was one of
                these.)</p>

            <p>With package managers life is vastly better. I was recently
                reminded of this when I tried to install the code-review tool
                <a href="http://www.reviewboard.org/" class="external">Review
                    Board</a>, which was too young to be in any package and
                depended on cutting-edge version of other libraries, also not in
                any package. I spent two full days failing to get all the
                related software installed properly.</p>

            <p>And yet by removing the initial hurdle to installing a program,
                packages create a large hurdle to scratching an itch. Today if
                I want to add a flag to &ldquo;netcat&rdquo; (which I did years ago to add
                a delay), it would be enough work that I wouldn&rsquo;t bother.
                Before package managers we were <em>forced</em> to do the work,
                which then made it easy to tweak the code. It also made it easy
                to examine core dumps when programs crashed.</p>

            <p>I was excited to try the Linux distribution Gentoo years ago
                because <em>everything</em> is compiled from scratch, but I
                found that they weren&rsquo;t keeping the source around in a way that
                you could easily go in and mess with. Perhaps I missed a
                configuration setting somewhere.</p>

            <p>I suspect that package managers have substantially hurt the open
                source movement. They&rsquo;ve raised the bar of the commitment
                needed to contribute. As Wikipedia has shown, it&rsquo;s critical to
                have a large number of people who just want to fix small things
                here and there. I wish Ubuntu had a flag to &ldquo;apt-get install&rdquo;
                that would install from source Gentoo-style and keep the whole
                thing in your home directory where you could muck with it.</p>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[Fields are Globals]]></title>
        <link>http://www.teamten.com/lawrence/writings/fields_are_globals.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/fields_are_globals.html</guid>
        <pubDate>21 Apr 2010</pubDate>
        <description><![CDATA[

            <p class="very-first">Everyone knows global variables are bad.
                They&rsquo;re bad because they can obscure the path the data takes
                through the code. You can set a global in one function and read
                it in another, and it&rsquo;s not clear that these two functions are
                passing data between them. It&rsquo;s more clear to pass the data as
                function parameters or return values.</p>

            <p>And although everyone knows this, they still do it every day in
                object-oriented programs, except the globals are now called
                &ldquo;fields&rdquo;. Setting a field in one method and reading it in
                another is just as bad as doing so with a global variable, but
                because the variable is inside an object on the heap somehow it
                has become okay. It&rsquo;s not; it&rsquo;s just as bad and it should be
                avoided. You must think of all fields as globals and minimize
                their use.</p>

            <p>Whenever possible, make fields &ldquo;final&rdquo; (in Java) and pass
                mutable data around through method parameters and return
                values. This can be hard in Java when returning multiple
                values, but it&rsquo;s still better to make a one-off class to hold
                both values than it is to use fields as a way to pass data
                around. At least it&rsquo;s clear how the data is moving through your
                code.</p>

            <p>Update 4/25/2010: I want to clarify that I&rsquo;m only addressing the
                case of a single call from a user of a class. If the user calls
                the class two different times, then clearly a field might be
                necessary to keep state between the calls. I&rsquo;m objecting to
                this kind of code:</p>

            <pre>
    public void doSomething() {
        mStatus = OK;
        doSomethingHelper();
        if (mStatus != OK) {
            fail();
        }
    }

    private void doSomethingHelper() {
        if (problem) {
            mStatus = FAIL;
        }
    }</pre>

            <p class="first">The status could have just been returned from the
                second method. Here&rsquo;s a case where the variable could have been
                passed in:</p>

            <pre>
    public void doSomething() {
        mParameter = ...;
        doSomethingHelper();
    }

    private void doSomethingHelper() {
        if (mParameter == ...) {
            ...;
        }
    }</pre>

            <p class="first">I see the above two patterns distressingly often, and
                from people who would never dream to do the same thing with a global
                variable in C.</p>
        ]]></description>
    </item>

    <item>
        <title><![CDATA[dynamic_cast&lt;std::integer&gt;(C)++]]></title>
        <link>http://www.teamten.com/lawrence/writings/dynamic_cast_std_integer_c.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/dynamic_cast_std_integer_c.html</guid>
        <pubDate>29 Mar 2010</pubDate>
        <description><![CDATA[

            <p class="author">Drew Olbrich and Lawrence Kesteloot</p>

            <p class="very-first">The C++ Standard Committee has been hard
                at work defining the next version of the language. Here&rsquo;s
                a provisional list of changes to be included:</p>

            <ol>
                <li><p class="first">For consistency with strings, integers have been split into
                        built-in constants of type <tt>int</tt> (3, 100, 0xFF, etc.) and
                        the <tt>std::integer</tt> class. The class has operator overloading
                        to make math easy. The built-in <tt>int</tt> type no longer has
                    these operators. Constants must be cast to the class for
                    the operators to work:</p>

                    <pre>
    Before: 5 + 6
    After: std::integer(5) + 6</pre>

                    <p class="first">Note that the 6 does not have to be cast because the +
                        operator is overloaded to take integer constants,
                        conveniently casting them for you. This new consistency
                        between integers (and floats, doubles, char, bool,
                        etc.) and strings will reduce confusion.</p></li>

                <li><p class="first">Functions often want to return pointers to local
                        variables, or pass pointers to local variables to other
                        functions. This isn&rsquo;t safe because when the stack is
                        unwound, those pointers are no longer valid.  This has
                        been fixed in the new standard by extending the
                        lifetime of local variables indefinitely. The
                        programmer is responsible for releasing the memory
                        explicitly. For example:</p>

                    <pre>
    int add(int a, int b)
    {
        std::integer sum = std::integer(a) + b;
 
        delete &amp;a;
        delete &amp;b;
 
        int sum_value = sum.c_int();
 
        delete &amp;sum;
 
        return sum_value;
    }</pre>

                        <p class="first">The local variable <tt>sum</tt> was
                            explicitly freed. Note that the
                        parameters also had to be freed. Did you spot the bug? The local
                        variable <tt>sum_value</tt> was returned (by value),
                            but its address was never
                        freed, resulting in a memory leak. APIs will have to be carefully
                        documented to specify whose responsibility it is (caller or callee)
                        to free both passed-in parameters and returned values.
                        Addresses can be returned by reference parameters to
                        pointers to variables, but remember to free those pointers
                        too.</p></li>

                <li><p class="first">Current C++ compilers must maintain
                        complicated data structures of
                        the functions that are declared or used in each source file, in order
                        to generate the appropriate binary object files. In order to reduce
                        this burden on the compiler, footer files have been introduced. These
                        are files that are included at the bottom of a .cpp file, which
                        summarize all functions that are defined or used by that file. The
                        format is somewhat different than a traditional .hpp file (because the
                        needs of the compiler are different there). The standard recommends
                        the extension .fpp for declaring these methods and
                        their signatures.</p></li>

                <li><p class="first">To remove the confusion over the
                        distinction between the <tt>NULL</tt> constant,
                        the &ldquo;0&rdquo; constant (for pointers), and C++0x&rsquo;s <tt>nullptr</tt> constant,
                        and to increase type safety, the null constant is now a template:</p>

                    <pre>
    MyClass *ptr = std::pointer_constants&lt;MyClass *&gt;::null();</pre></li>

                <li><p class="first">Implementing the Singleton Pattern (Gamma
                        <em>et al</em>) requires writing the boilerplate method
                        to create a single instance. To facilitate
                    this common pattern, the language introduces the keyword &ldquo;old&rdquo;. The
                    program should create one instance of the object at start-up:</p>

                    <pre>
    MyClass *ptr = new MyClass;</pre>

                    <p class="first">and other methods can get a reference to that instance
                        using the following construct:</p>

                    <pre>
    MyClass *ptr = old MyClass;</pre>

                    <p class="first">If there are several instances of MyClass in
                        the heap, it is undefined which one is chosen. If there are
                        no instances, a null reference is returned (see
                        previous item). Be careful to
                        not accidentally get a reference to an object on the stack.</p></li>

                <li><p class="first">To reflect the enhancements to the
                        language since 1983, the name of the language has been changed to:
                        <tt>dynamic_cast&lt;std::integer&gt;(C)++</tt>.</p></li>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[In Defense of Design Patterns]]></title>
        <link>http://www.teamten.com/lawrence/writings/in_defense_of_design_patterns.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/in_defense_of_design_patterns.html</guid>
        <pubDate>06 Oct 2009</pubDate>
        <description><![CDATA[

            <p class="very-first">It&rsquo;s fashionable to bash software design patterns.
                &ldquo;The Singleton Pattern? You mean, <em>a global variable?</em>
                Hahaha!&rdquo; It&rsquo;s hilarious. But I&rsquo;ve noticed that those who
                mock are also, curiously, those who&rsquo;ve not learned about them.
                I think they (the patterns) serve a useful purpose.</p>

            <p>My analogy is to data structures. Imagine that we didn&rsquo;t have
                names for data structures, and you had to repeatedly say,
                &ldquo;Let&rsquo;s put data in objects where each object has a reference
                to the next object, and the last reference is null, and we keep
                track of only the first one.&rdquo; It&rsquo;d be hard to communicate. There&rsquo;s
                a bunch of information in your head associated with the name
                <em>linked list</em> and without the term you wouldn&rsquo;t be
                able to organize it or communicate effectively about it.</p>

            <p>Design patterns are just that: names for common ways of organizing
                code, so instead of saying, &ldquo;Let&rsquo;s make a class that you can
                configure and then ask it to atomically make another object so
                that the other object doesn&rsquo;t need a long constructor or ever
                be in a half-constructed state,&rdquo; you can just say, &ldquo;Let&rsquo;s use
                the Builder Pattern.&rdquo; Along with the name comes a shared understanding
                of how and when to implement it, advantages and drawbacks, and
                what to call the class.</p>

            <div class="book-cover" style="float:right"><a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;tag=lkesteloot&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201633612"><img border="0" src="51Rs5KgdLTL._SL160_.jpg"></a><img src="http://www.assoc-amazon.com/e/ir?t=lkesteloot&amp;l=as2&amp;o=1&amp;a=0201633612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></div>

            <p>People often crack open a pattern book and say, &ldquo;There&rsquo;s nothing
                new here!&rdquo; That&rsquo;s the <em>point</em>. It&rsquo;s for code structures that
                we&rsquo;ve been using for a long time but never had a name for.
                In fact, seen that way, it&rsquo;s a bit ridiculous
                to bash design patterns. Why <em>wouldn&rsquo;t</em> you want to
                name a commonly-used thing?</p>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[Asking &ldquo;Why&rdquo; in Interviews]]></title>
        <link>http://www.teamten.com/lawrence/writings/asking_why_in_interviews.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/asking_why_in_interviews.html</guid>
        <pubDate>01 Oct 2009</pubDate>
        <description><![CDATA[

            <p class="very-first">The question &ldquo;Why?&rdquo; can be interpreted
                to mean &ldquo;What&rsquo;s the cause?&rdquo; or &ldquo;What&rsquo;s the purpose?&rdquo;
                Why do you go to work every day? The cause is the employment
                agreement, the purpose is to make money. Some questions have
                only a cause (&ldquo;Why do you like spinach?&rdquo; &ldquo;Why did the sun
                rise this morning?&rdquo;).</p>

            <p>In everyday conversations I try to ask the unambiguous form
                of the question, but when interviewing job candidates I&rsquo;ve
                found it useful to keep it ambiguous to see which one they&rsquo;ll
                pick. It reflects something about the way they think.</p>

            <p>For example, I&rsquo;ll ask a senior database administrator (DBA)
                candidate what
                style he uses to name tables (capitalization, prefixes,
                underscores, pluralization). I have a preferred answer
                to this, but whatever answer they give
                I&rsquo;ll ask, &ldquo;Why?&rdquo; Most candidates will interpret this to
                mean, &ldquo;What&rsquo;s the cause?&rdquo; and will answer &ldquo;Because that&rsquo;s
                what the style guidelines say at my company.&rdquo;</p>

            <p>At this point the interview is pretty much over, but I&rsquo;ll usually
                ask something like, &ldquo;Well what if you worked here?&rdquo; The
                answer is usually, &ldquo;I&rsquo;d follow your guidelines.&rdquo;</p>

            <p>&ldquo;What if you had to write the guidelines?&rdquo;</p>
            <p>&ldquo;I&rsquo;d use the same ones.&rdquo;</p>
            <p>&ldquo;Why?&rdquo; (again)</p>
            <p>&ldquo;Cause that&rsquo;s what&rsquo;s in the guidelines of the company I work for now.&rdquo;</p>

            <p>At no point is the candidate considering the &ldquo;purpose&rdquo; interpretation,
                which is the interpretation I&rsquo;d expect from a senior candidate.
                He should be thinking about the benefits of the style he&rsquo;s using
                over the alternatives. Not doing so shows a lack of introspection,
                and someone who doesn&rsquo;t introspect won&rsquo;t improve and isn&rsquo;t senior.</p>

            <p>My ideal conversation would go something like this:</p>
            <p>&ldquo;What style do you use for table names?&rdquo;</p>
            <p>&ldquo;All lower case, with underscores between words, singular.&rdquo;</p>
            <p>&ldquo;Why?&rdquo;</p>
            <p>&ldquo;Uppercase can cause problems in some dialects because of the
                case-insensitive nature of the parsers, and you&rsquo;ll get different
                results on Windows and Unix with MySQL because they use the table name
                for filenames. Underscores make it more readable, and singular reads
                better in most places (though not in the actual join clause).&rdquo;</p>
            <p>At that point the interview is also over, but in a good way.</p>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[Every Line Is a Potential Bug]]></title>
        <link>http://www.teamten.com/lawrence/writings/every_line_is_a_potential_bug.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/every_line_is_a_potential_bug.html</guid>
        <pubDate>19 Sep 2009</pubDate>
        <description><![CDATA[

            <p class="very-first">Last summer I wrote some code to get
                a message out of a hash table. The message was going to be put
                there by another thread. There was a small chance of a race
                where it wouldn&rsquo;t be there yet when I initially looked for it.
                The code looked something like this:</p>

            <pre>
    while ((message = map.get(key)) == null
        &amp;&amp; System.currentTimeMillis() &lt; timeoutTime) {

        wait(1000);
    }</pre>

            <p class="first">The <tt>wait()</tt> call blocks the thread,
                waiting for the <tt>notifyAll()</tt> from the thread that puts
                the message into the map.  The 1000 means one second. The
                timeout was going to be on the order of five seconds.</p>

            <p>The above code is simple and correct. It&rsquo;ll just keep looping until
                the value comes in or until it has timed out. The timeout may go
                over by up to one second, but that&rsquo;s not a problem in this case.
                (Or rather, by the time that happens, you&rsquo;ve got more serious problems.)</p>

            <p>The code was reviewed by two other people. Both complained that the
                <tt>wait()</tt> should wait for the time between now and the timeout,
                not just one second. They argued that my code wakes up the thread
                five times unnecessarily. I replied that the key was very
                likely to be there within the first second, and that waking up
                a thread is not very expensive. I argued that their proposed code
                was more complex, and therefore more likely to have bugs.</p>

            <p>They both said, <em>&ldquo;One subtraction is not complex!&rdquo;</em>, went
                back to their desks, and emailed me their modified versions, just
                to prove how simple it could be. Both had introduced a bug.
                One person&rsquo;s bug was straightforward: he used the wrong
                constant for the calculation.  But the second person&rsquo;s bug was
                subtle:</p>

            <pre>
    while ((message = map.get(key)) == null
        &amp;&amp; System.currentTimeMillis() &lt; timeoutTime) {

        wait(<span class="code_highlight">timeoutTime - System.currentTimeMillis()</span>);
    }</pre>

            <p class="first">There&rsquo;s a small chance that the current time will
                have advanced by the time the subtraction is done, resulting in
                a negative value passed to <tt>wait()</tt> and an
                <tt>IllegalArgumentException</tt> getting thrown. In order to
                save the computer one rare thread switch, he introduced a bug
                that would have occasionally and mysteriously caused operations
                to fail.</p>

            <div class="update">
                <p>Update 3-15-2010: Ajit Mandalay pointed out another bad
                    scenario: the subtraction yields 0, which means &ldquo;infinity&rdquo;,
                    and the loop potentially never exits.</p>
            </div>

            <p>Every line of code you write is a potential bug. Do not write any
                line of code unless you absolutely need it <em>right now</em> and
                your program will suffer for the lack of it. Do not write routines
                speculatively. Do not write abstraction layers you don&rsquo;t need right
                now. If an optimization will add any complexity whatsoever, even
                a subtraction, resist it. You will be sorry in five years when
                your code is riddled with potentially-buggy code that you never
                really needed to write.</p>

        ]]></description>
    </item>

    <item>
        <title><![CDATA[Hiring in a Recession]]></title>
        <link>http://www.teamten.com/lawrence/writings/hiring_in_a_recession.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/hiring_in_a_recession.html</guid>
        <pubDate>15 Sep 2009</pubDate>
        <description><![CDATA[

            <p class="very-first">You&rsquo;d think that in a recession
                companies would have an easier time hiring. They should
                be flooded by resumes because of the high unemployment
                rate. But I think that recruiting actually gets harder,
                for two reasons.</p>

            <p>The first is that many lay-offs are
                actually firings. Companies don&rsquo;t dare fire too many
                people when times are good because the public may
                perceive the company as having problems. But in a
                recession the company can get rid of its 10% lowest-performing
                employees and blame it on the economy. Some companies
                do get rid of entire projects, where both good and
                poor employees are lost, but hiring is so difficult
                that a company will typically try to keep the best
                employees before flushing the rest.</p>

            <p>The second reason is that good employees, those not
                getting laid off, hold on more tightly to their jobs.
                An employee might normally be thinking, &ldquo;This job
                isn&rsquo;t so great, I bet I could do better.&rdquo; In a recession,
                though, he&rsquo;ll be thankful just to be employed.
                His current situation is likely to seem more stable
                and safe than a position in another company.</p>

            <p>During a recession, then, companies with good hiring
                standards must find it harder to hire, because although
                they are flooded with resumes, those resumes are of lower
                average quality.</p>
        ]]></description>
    </item>

    <item>
        <title><![CDATA[Paid Vacation]]></title>
        <link>http://www.teamten.com/lawrence/writings/paid_vacation.html</link>
        <author>Lawrence Kesteloot</author>
        <guid isPermaLink="true">http://www.teamten.com/lawrence/writings/paid_vacation.html</guid>
        <pubDate>10 Sep 2009</pubDate>
        <description><![CDATA[

            <p class="very-first">When you quit a salaried job, you get a check
                for the vacation days you have left. They calculate the daily
                rate using your pro-rated salary. Every vacation day you take
                now is one less day&rsquo;s worth of pay that you&rsquo;ll get when
                you quit. So there&rsquo;s no such thing as &ldquo;paid vacation&rdquo;. It&rsquo;s all
                unpaid: &ldquo;unpaid&rdquo; vacation is unpaid today, whereas &ldquo;paid&rdquo;
                vacation is unpaid later.</p>

            <p>One exception is when you max out your vacation days. Then
                you may as well take them or they&rsquo;re lost anyway.</p>

            <p>I unfortunately discovered this ten years ago, and ever since
                then my vacations have cost a lot more because I count
                the reduced check that I&rsquo;ll get when I eventually quit.</p>
        ]]></description>
    </item>

</channel>
</rss>

