<?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>Made of Bugs &#187; programming</title>
	<atom:link href="http://blog.nelhage.com/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Using Haskell&#8217;s &#8216;newtype&#8217; in C</title>
		<link>http://blog.nelhage.com/2010/10/using-haskells-newtype-in-c/</link>
		<comments>http://blog.nelhage.com/2010/10/using-haskells-newtype-in-c/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 17:11:25 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[JOS]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[newtype]]></category>
		<category><![CDATA[operating systems]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=364</guid>
		<description><![CDATA[A common problem in software engineering is avoiding confusion and errors when dealing with multiple types of data that share the same representation. Classic examples include differentiating between measurements stored in different units, distinguishing between a string of HTML and a string of plain text (one of these needs to be encoded before it can [...]]]></description>
			<content:encoded><![CDATA[<p>A common problem in software engineering is avoiding confusion and
errors when dealing with multiple types of data that share the same
representation. Classic examples include differentiating between
measurements stored in different units, distinguishing between a
string of HTML and a string of plain text (one of these needs to be
encoded before it can safely be included in a web page!), or keeping
track of pointers to physical memory or virtual memory when writing
the lower layers of an operating system&#8217;s memory management.</p>

<p>Unless we&#8217;re using a richly-typed language like Haskell, where we can
use <a href="http://blog.ezyang.com/2010/08/type-kata-newtypes/"><code>newtype</code></a>, the best solutions tend to just rely on
convention. The much-maligned <a href="http://en.wikipedia.org/wiki/Hungarian_Notation">Hungarian Notiation</a> evolved
in part to try to combat this sort of problem &#8212; If you decide on a
convention that variables representing physical addresses start with
<code>pa</code> and virtual addresses start with <code>va</code>, then anyone who encounters
a <code>uintptr_t pa_bootstack;</code> can immediately decode the intent.</p>

<p>It turns out, though, that we can get something very much like
<code>newtype</code> in familiar old C. Suppose we&#8217;re writing some of the paging
code for a toy x86 architecture. We&#8217;re going to be passing around a
lot of physical and virtual addresses, as well as indexes of pages in
RAM, and it&#8217;s going to be easy to confuse them all. The traditional
solution is to use some <code>typedef</code>s, and then promise to be very
careful to mix them up:</p>

<pre><code>typedef uint32_t physaddr_t;
typedef uint32_t virtaddr_t;
typedef uint32_t ppn_t;
</code></pre>

<p>We have to promise not to mess up, though &#8212; the compiler isn&#8217;t going
to notice if I pass a <code>ppn_t</code> to a function that wanted a
<code>physaddr_t</code>.</p>

<p>This example was inspired by JOS, a toy operating system used by MIT&#8217;s
Operating Systems Engineering class. JOS remaps all of physical memory
starting at a specific virtual memory address (<code>KERNBASE</code>), and so
provides the following macros:</p>

<pre><code>/* This macro takes a kernel virtual address -- an address that points above
 * KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
 * and returns the corresponding physical address.  It panics if you pass it a
 * non-kernel virtual address.
 */
#define PADDR(kva)                                          \
({                                                          \
        physaddr_t __m_kva = (physaddr_t) (kva);            \
        if (__m_kva &lt; KERNBASE)                                     \
                panic("PADDR called with invalid kva %08lx", __m_kva);\
        __m_kva - KERNBASE;                                 \
})

/* This macro takes a physical address and returns the corresponding kernel
 * virtual address.  It panics if you pass an invalid physical address. */
#define KADDR(pa)                                           \
({                                                          \
        physaddr_t __m_pa = (pa);                           \
        uint32_t __m_ppn = PPN(__m_pa);                             \
        if (__m_ppn &gt;= npage)                                       \
                panic("KADDR called with invalid pa %08lx", __m_pa);\
        (void*) (__m_pa + KERNBASE);                                \
})
</code></pre>

<p>Because the typedefs are unchecked by the compiler, though, it is a
common mistake to use a physical address where a virtual address is
meant, and nothing will catch it until your kernel triple-faults, and
a long, painful debugging session ensues.</p>

<p>Inspired by Haskell&#8217;s <code>newtype</code>, though, it turns out we can get the
compiler to check it for us, with a little more work, by using a
singleton <code>struct</code> instead of a <code>typedef</code>:</p>

<pre><code>typedef struct { uint32_t val; } physaddr_t;
</code></pre>

<p>If we wanted to be overly cute, we could even use a macro to mimic
Haskell&#8217;s <code>newtype</code>:</p>

<pre><code>#define NEWTYPE(tag, repr)                  \
    typedef struct { repr val; } tag;       \
    static inline tag make_##tag(repr v) {  \
            return (tag){.val = v};         \
    }                                       \
    static inline repr tag##_val(tag v) {   \
            return v.val;                   \
    }

NEWTYPE(physaddr, uint32_t);
NEWTYPE(virtaddr, uint32_t);
NEWTYPE(ppn,  uint32_t);
</code></pre>

<p>Given those definitions, <code>PADDR</code> and <code>KADDR</code> become:</p>

<pre><code>#define PADDR(kva)                                          \
({                                                          \
    if (virtaddr_val(kva) &lt; KERNBASE)                       \
            panic("PADDR called with invalid kva %08lx", virtaddr_val(kva)); \
    make_physaddr(virtaddr_val(kva) - KERNBASE);            \
})

#define KADDR(pa)                                           \
({                                                          \
    uint32_t __m_ppn = physaddr_val(pa) &gt;&gt; PTXSHIFT;        \
    if (__m_ppn &gt;= npage)                                   \
            panic("KADDR called with invalid pa %08lx", physaddr_val(pa)); \
    make_virtaddr(physaddr_val(pa) + KERNBASE);             \
})
</code></pre>

<p>We have to use some accessor and constructor functions, but in
exchange, we get strong type-checking: If you pass <code>PADDR</code> a physical
address (or anything other than a virtual address), the compiler will
catch it.</p>

<p>The wrapping and unwrapping is slightly annoying, but we can for the
most part avoid having to do it everywhere, by pushing the wrapping
and unwrapping down into some utility functions. For instance, a
relatively common operation at this point in JOS is creating a
page-table entry, given a physical address. If you want to construct
the PTE by hand, you need to use <code>physaddr_val</code> every time. But a
better plan is a simple utility function:</p>

<pre><code> static inline pte_t make_pte(physaddr addr, int perms) {
     return physaddr_val(addr) | perms;
 }
</code></pre>

<p>In addition to losing the need to unwrap the <code>physaddr</code> everywhere, we
gain a measure of clarity and typechecking &#8212; if you remember to use
<code>make_pte</code>, you&#8217;ll never accidentally try to insert a virtual address
into a page table.</p>

<p>We can add similar functions for converting between types, as well a a <code>struct
Page</code>, used to track metadata for a physical page. As an experiment, I went and
reimplemented JOS&#8217;s memory management primitives using these definitions, and
only needed to use <code>FOO_val</code> or <code>make_FOO</code> a very few times outside of the
header files that defined <code>KADDR</code> and friends.</p>

<h2>Performance</h2>

<p>While the typechecking is nice, any C programmer implementing a
memory-management system is probably going to want to know: How much does it
cost me? You&#8217;re creating and unpacking these singleton <code>struct</code>s everywhere &#8211;
does that have a cost?</p>

<p>The answer, though, in almost all cases is &#8220;no&#8221; &#8212; A half-decent compiler will
optimize the resulting code to be completely identical to the code without the
<code>struct</code>s, in almost all cases.</p>

<p>Also, the in-memory representation of the <code>struct</code> is going to be exactly the
same as the bare value &#8212; it&#8217;s even guaranteed to have the same alignment and
padding constraints, so if you need to embed a <code>physaddr</code> inside another struct,
or into an array, the representation is identical to the <code>physaddr_t</code> typedef.</p>

<p>On i386, parameters are passed on the stack, so that means that passing the
struct is identical to passing the <code>uint32_t</code>. On amd64, as described last week,
small structures are passed in registers, and so, again, the calling convention
is identical.</p>

<p>Unfortunately, the i386 ABI specifies that returned <code>struct</code>s always go on the
stack (while integers go in <code>%eax</code>), so you do pay slightly if you want to
return one of these typedef&#8217;d objects. <code>amd64</code> will also break it down into a
register, though, so on a 64-bit machine it&#8217;s again identical.</p>

<p>If you&#8217;re worried, though, you can always use the preprocessor to make the
checks vanish for a production build:</p>

<pre><code>#ifdef NDEBUG
#define NEWTYPE(tag, repr)                  \
    typedef repr tag;                       \
    static inline tag make_##tag(repr v) {  \
            return v;                       \
    }                                       \
    static inline repr tag##_val(tag v) {   \
            return v;                       \
    }
#else
/* Same definition as above */
#endif
</code></pre>

<p>Because the types have identical representations, you can safely
serialize your structs and exchange them between code compiled with
either version. On amd64, you can probably even call between
compilation units defined either way.</p>

<p>The next time you&#8217;re writing some subtle C code that has to deal with multiple
types with the same representation, I encourage you to consider using this
trick.</p>

<h2>Addendum</h2>

<p>I didn&#8217;t invent this trick, although as far as I know the <code>NEWTYPE</code> macro is my
own invention (<em>Edited to add: A commenter points out that I&#8217;m not the first
to <a href="http://notanumber.net/archives/33/newtype-in-c-a-touch-of-strong-typing-using-compound-literals">use the <code>newtype</code> name in
C</a>,
although I think I prefer my implementation</em>).</p>

<p>. I learned this trick from the Linux kernel, which uses it for a
very similar application &#8212; distinguishing entries in different levels of the
x86 page tables. <code>page.h</code> on amd64 includes following definitions [Taken from an
old version, but the current version has equivalent ones):</p>

<pre><code>/*
 * These are used to make use of C type-checking..
 */
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pud; } pud_t;
typedef struct { unsigned long pgd; } pgd_t;
</code></pre>

<p>I claimed above that the struct and the bare type will have the same alignment
and padding. I don&#8217;t believe this is guaranteed by C99, but the SysV amd64 and
i386 ABI specifications both require:</p>

<blockquote>
Structures and unions assume the alignment of their most strictly aligned
component. Each member is assigned to the lowest available offset with the
appropriate alignment. The size of any object is always a multiple of the
object’s alignment.
</blockquote>

<p>(text quoted from the amd64 document, but the i386 one is almost identical).</p>

<p>And C99 requires (§6.7.2.1 para 13):</p>

<blockquote>
… A pointer to a structure object, suitably converted, points to its initial
member (or if that member is a bit-field, then to the unit in which it resides),
and vice versa. There may be unnamed padding within a structure object, but not
at its beginning.
</blockquote>

<p>I believe these requirements, taken together, should be enough to ensure that
the <code>struct</code> and the bare type will have the same representation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/10/using-haskells-newtype-in-c/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Some musings on ORMs</title>
		<link>http://blog.nelhage.com/2010/07/some-musings-on-orms/</link>
		<comments>http://blog.nelhage.com/2010/07/some-musings-on-orms/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 22:38:23 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[dynamic analysis]]></category>
		<category><![CDATA[musings]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=278</guid>
		<description><![CDATA[I&#8217;m pretty sure every developer who has ever worked with a modern database-backed application, particularly a web-app, has a love/hate relationship with their ORM, or object-relational mapper. On the one hand, ORMs are vastly more pleasant to work with than code that constructs raw SQL, even, generally, from a tool that gives you an object [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pretty sure every developer who has ever worked with a modern
database-backed application, particularly a web-app, has a love/hate
relationship with their <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a>, or object-relational mapper.</p>

<p>On the one hand, ORMs are vastly more pleasant to work with than code
that constructs raw SQL, even, generally, from a tool that gives you
an object model to construct SQL, instead of requiring (Cthulhu help
us all) string concatenation or interpolation.</p>

<p>On the other hand, there tends to be an enormous mismatch between the
objects the ORM is modelling on one end, and the relational database
on the back end. Basically, the object model encourages dealing with
one object at a time, whereas the relational database wants you to
push your queries, JOINs, and even your entire transactions back into
it, so that it can better optimize them for you. And so, you tend to
have a choice between writing shockingly inefficient code, and jumping
through weird hoops and strange syntax to give your ORM the tools to
generate efficient queries.</p>

<p>The most fundamental problem, perhaps, is the question of how much
data the ORM should request from the database. When I ask for a
collection of objects (using some syntax to generate the SQL <code>WHERE</code>
clause automatically), the ORM has to decide:</p>

<ul>
<li>Which fields in the object should the ORM <code>SELECT</code> from the
database, and</li>
<li>Which associated models (with foreign keys to or from the object in
question) the ORM should <code>JOIN</code> in and pull out at the same time.</li>
</ul>

<p>(You can think of the second as a more involved version of the first,
but involves more complexity, and is interesting for being potentially
recursive).</p>

<p><code>SELECT</code>ing too much data in either case makes the database do too
much work, touch too many blocks on disk, read too many indexes, and
so on, and makes your queries slow. <code>SELECT</code>ing not enough data means
your ORM needs to go back and make additional queries when you ask for
fields or models that were not pulled in initially, killing your
performance even more.</p>

<p>I&#8217;d like to muse about two possible solutions, neither of which I&#8217;m
aware of implementations of, although to be honest I haven&#8217;t looked
too hard. I&#8217;d love it if anyone could point me at work on either sort.</p>

<h2>The static solution</h2>

<p>Given a language with a sufficiently awesome type system (Haskell
comes to mind :)), you could imagine encoding information about which
fields and models are or are not <code>SELECT</code>ed into the type of a record
object, making it statically an error to write a query that
under-selects. Given type inference, we can probably even go on to
statically infer (probably with a bit of programmer help in the form
of type annotations) which fields and models we need to <code>SELECT</code>,
based precisely on which fields of the result get accessed.</p>

<p>This is the kind of solution that occurs immediately to a certain type
of person (of which I know a lot) when they think about this type of
problem enough. It&#8217;s fun to think about and there are probably some
papers in it (if no one&#8217;s beaten you to it), but I suspect it&#8217;s the
kind of thing that&#8217;s unlikely to gain much traction among mainstream
developers, if only because it would require you write in Haskell or
equivalent.</p>

<h2>The dynamic solution</h2>

<p>Another solution occurred to me recently, which I don&#8217;t think I&#8217;ve
heard people talking about. I like it because I&#8217;m pretty sure it could
be grafted onto an existing ORM with little or no API change, which
means there&#8217;s potential for incrementel adoption and improvement.</p>

<p>The key insight here is that, while the decision of what to <code>SELECT</code>
is critical for performance, it&#8217;s (mostly)<a href="#fn1"><sup>1</sup></a> irrelevant for correctness whether you
have to make additional queries later, or pull in too much data. A
good ORM, if it notices you ask for a field it doesn&#8217;t have cached,
will just go ahead and make the <code>SELECT</code> for you.</p>

<p>This opens the door for heuristic solutions. A good ORM will already
have hooks for the programmer to specify which fields or models to
include or exclude &#8212; <a href="http://www.djangoproject.com/">Django</a>, to pick a popular example, has
the <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.QuerySet.select_related"><code>select_related</code></a> and <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.QuerySet.defer"><code>defer</code></a> methods on
its <code>QuerySet</code>s.</p>

<p>So, my proposal is this: Let&#8217;s develop tools to profile an
application, and automatically generate those annotations in a
profile-driven manner. Since all accesses to your data are through the
ORM, we can instrument the ORM to determine which fields are selected
after a query, and remember that information for next time it sees the
same query.</p>

<p>In a webapp environment, the possibilities for optimization get
potentially even more exciting. A webapp framework like Django knows
an awful lot of information at any given moment, like what user is
logged into your app, and what URL is currently being generated. We
could imagine associating that data with the profile results, so that
the ORM could automatically discover relations between the application
structure and the ORM queries. It could &#8220;learn&#8221;, for example, that
certain users are administrators, and so will access more fields on
certain models than other users. It could learn that even though
<code>/places/list/</code> and <code>/places/details/</code> pull up the exact same set of
models (maybe even through the same helper function!), the former
needs only their names and IDs, while the latter needs to pull in full
details, as well as rows from the associated <code>reviews</code> table.</p>

<p>All without a single programmer annotation. Of course, in cases where
the behavior is too complex for the tool&#8217;s heuristics to pick up, or
where the programmer absolutely needs predictable behavior or needs to
micro-optimize, you could turn off the heuristics and fall back the
old behavior (with the same old annotations available to the
programmer).</p>

<p>Is anyone aware of any work in this space? It sounds like a
potentially extremely exciting project to me, but I probably don&#8217;t
have the time to attempt to throw together an implementation.</p>

<p><small><a name="fn1">1.</a>Ignoring, for example, race conditions
where you need to select a model and related models atomically, and
don&#8217;t want or can&#8217;t afford a transaction around the entire lifetime of
the objects in the app code.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/07/some-musings-on-orms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Check Plus: An EDSL for writing unit tests in C</title>
		<link>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/</link>
		<comments>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 19:54:53 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=263</guid>
		<description><![CDATA[Check is an excellent unit-testing framework for C code, used by a number of relatively well-known projects. It includes features such as running all tests in separate address spaces (using fork(2)), which means that the test suite can properly report segfaults or similar crashes without the test runner crashes. My main complaint about Check is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://check.sourceforge.net/">Check</a> is an excellent unit-testing framework for C code, used
by a number of relatively well-known projects. It includes features
such as running all tests in separate address spaces (using
<code>fork(2)</code>), which means that the test suite can properly report
segfaults or similar crashes without the test runner crashes.</p>

<p>My main complaint about Check is that (unsurprisingly for a framework
written in C), it&#8217;s not very declarative. After you define all your
tests as separate functions, you need to write code to manually
collect them into &#8220;test cases&#8221;, which you then collect into &#8220;test
suites&#8221;, which you can then run. While this is an understandable
interface for a C library to provide, as a user I found that it
rapidly annoyed me, and so I wrote Check Plus.</p>

<p><a href="http://github.com/nelhage/check-plus">Check Plus</a> is a simple library I wrote that uses some preprocessor
tricks and GNU C extensions to provide a declarative EDSL within C for
declaring and collecting your test cases. Check-Plus is a single
self-contained header file distributed under the LGPL (like Check), so
it should be easy to pull into your project.</p>

<h2>Example</h2>

<p>Check-Plus lets you declare your Check suites and test cases in a
declarative manner. A simple example, shipped with Check-Plus, would
look like:</p>

<pre><code>#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

#include "check-plus.h"

#define SUITE_NAME example
BEGIN_SUITE("Example test suite");

#define TEST_CASE core
BEGIN_TEST_CASE("Core tests");

TEST(strcmp)
{
    fail_unless(strcmp("hello", "HELLO") != 0);
    fail_unless(strcasecmp("hello", "HELLO") == 0);
}
END_TEST

TEST(strcat)
{
    char buf[1024] = {0};
    strcat(buf, "Hello, ");
    strcat(buf, "World.");
    fail_unless(strcmp(buf, "Hello, World.") == 0);
}
END_TEST

END_TEST_CASE;
#undef TEST_CASE
END_SUITE;
#undef SUITE_NAME
</code></pre>

<p>Having done that, you can extract the declared test suite using
<code>construct_test_suite(example)</code>, and run it using the standard Check
test runner tools.</p>

<p>You can, of course, define multiple test cases within a single suite,
and you can even define test fixtures using</p>

<pre><code>DEFINE_FIXTURE(setup, teardown);
</code></pre>

<p>within the <code>BEGIN_TEST_CASE</code> &#8230; <code>END_TEST_CASE</code> block.</p>

<p>The equivalent code, without Check-Plus, would look similar, but
instead of the <code>BEGIN_</code> and <code>END_</code> blocks to define the suite and test case, you&#8217;d have to write
something like:</p>

<pre><code>Suite *
example_suite (void)
{
  Suite *s = suite_create ("Example test suite");

  /* Core test case */
  TCase *tc_core = tcase_create ("Core tests");
  tcase_add_test (tc_core, test_strcmp);
  tcase_add_test (tc_core, test_strcat);
  suite_add_tcase (s, tc_core);

  return s;
}
</code></pre>

<p>It&#8217;s not a huge difference, but it&#8217;s big enough that I really
appreciate it once the test suite gets large. For more documentation on Check, check out <a href="http://check.sourceforge.net/doc/check_html/index.html">its manual</a>.</p>

<p>Let me know if you find this useful for anything. Next week, I&#8217;ll do a
writeup on the tricks behind the implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Confessions of a programmer: I hate code review</title>
		<link>http://blog.nelhage.com/2010/06/i-hate-code-review/</link>
		<comments>http://blog.nelhage.com/2010/06/i-hate-code-review/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 00:21:11 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[ksplice]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=241</guid>
		<description><![CDATA[Most of the projects I&#8217;ve been working on today have fairly strict code review policies. My work requires code review on most of our code, and as we bring on an army of interns for the summer, I&#8217;ve been responsible for reviewing lots of code. Additionally, about five months ago BarnOwl, the console-based IM client [...]]]></description>
			<content:encoded><![CDATA[<div id="text-1">

<p>
Most of the projects I&#8217;ve been working on today have fairly strict
code review policies. My <a href="http://www.ksplice.com">work</a> requires code review on most of our
code, and as we bring on <a href="http://blog.ksplice.com/2010/03/quadruple-productivity-with-an-intern-army/">an army of interns</a> for the summer, I&#8217;ve been
responsible for reviewing lots of code. Additionally, about five
months ago <a href="http://barnowl.mit.edu/">BarnOwl</a>, the console-based IM client I develop, adopted an
official pre-commit review policy. And I have a confession to make: I
hate mandatory code review.
</p>
<p>

I should be clear that I think I still <b>believe</b> in code review
as a useful tool for developers working together on a project. A
reviewer will flag as bad style or inefficient or ugly things that you
let slide working for yourself. A reviewer comes at code without the
assumptions of how it&#8217;s supposed to work that you made, and can often
spot errors you made because mixed up a mental model of your intent
with the code you actually wrote.
</p>

<p> In addition, code review is a great way to ensure that at least
two people are familiar with each piece of your infrastructure. There
is often a natural tendency for different developers to take ownership
of specific pieces of code or infrastructure, and be the only ones who
touch or maintain it. But then it breaks while they&#8217;re on vacation,
and everyone else is left trying to figure out how this code was ever
supposed to work. A mandatory code review policy is often a great way
to mitigate that class of problem.
</p>

<p> But, theoretical and observed benefits of code review aside,
speaking personally, as both a developer and as a reviewer, I&#8217;ve been
finding it a really frustrating process.  </p>

</div>

<div id="outline-container-1.1" class="outline-3">
<h3 id="sec-1.1">As an author </h3>
<div id="text-1.1">


<p>
As a developer, I hate that code review adds unpredictably long
latencies into my development workflow. Once I&#8217;ve finished and tested
a feature to my satisfaction, and sent it off for code review, I have
to wait for a potentially long time before I can actually mark it as
done. This means that, when deciding what to do next, I have
essentially three choices:
</p>
<ol>
<li>
Busy-wait. Get coffee, read reddit, and check my mail until the
review request comes back.

</li>
<li>
Continue development on top of the code I just sent for code
review.

</li>
<li>
Work on something completely different.

</li>
</ol>

<p>All three of these options suck. (1) is convenient if I can expect the
review to come back shortly, since doing something idle like reading
reddit or checking mail lets me keep the code in the back of my mind,
so I don&#8217;t have to page it back in when the review response comes
back. But obviously it&#8217;s inefficient, wasted time, and unacceptable if
I don&#8217;t expect a reply within an hour at most.
</p>
<p>
(2) is often what I want to be doing. I&#8217;ll often be working on a
project with several logically distinct but related stages. It often
makes sense to send out a review request for each, since they can be
deployed and reviewed separately.
</p>
<p>
However, if a reviewer comes back with significant comments on the
code I sent out, I now not only need to update that code, but I also
need to rebase the work I&#8217;ve done since then on top of the result,
which may be a real pain if I&#8217;m working on something closely related
(e.g. if my work used APIs I built previously, and the reviewer asks
for changes in those APIs in some way).
</p>
<p>
Option (3) avoids both problems, but means that I&#8217;m continually
swapping different projects in and out of focus. This slows me down,
since I have to constantly re-remember where I was in each project,
which APIs I was using, and so on. Any developer can tell you that
they hate switching between different projects too frequently.
</p>
<p>
Option (3) might be more tolerable with large projects, where
development/review cycles are on the order of weeks. But those aren&#8217;t
the projects I&#8217;m working on.
</p>
</div>

</div>

<div id="outline-container-1.2" class="outline-3">
<h3 id="sec-1.2">As a reviewer </h3>
<div id="text-1.2">


<p>
Reviewing code is one of those things that I would enjoy if I had
infinite time, but that I find a nuisance when I don&#8217;t. I do enjoy
reading other peoples&#8217; code and figuring out how it could be better,
and giving feedback to help get it there.
</p>
<p>
But doing so well takes a lot of time, and a lot of time is something
I rarely have these days. In addition, because of my above complaints
about dealing with code review as a developer, I&#8217;m always acutely
aware that someone is probably waiting on my reply in order to get
work done. So I always feel rushed to reply to code review requests,
as well.
</p>
<p>
So, even though I always feel like code review should be something I&#8217;m
enjoying, I tend to find it a frustrating experience where it just
feels like a task I have to do before I can get back to real work.
</p>
<p>

This is, of course, in part just a symptom of being too busy, but code
review makes it a task that bugs me more than other time drains. If a
customer reports a critical bug that I have to drop everything to
investigate, I&#8217;ll be annoyed, but I at least feel like I&#8217;m doing
something important that fixes a real problem and hopefully ends with
a happy customer. If I spend a day doing nothing but reading code
reviews, I&#8217;ll end up feeling unsatisfied and unproductive. Because
code review feels fundamentally optional &#8212; even though I believe it&#8217;s
beneficial, it&#8217;s something we&#8217;ve chosen to do, not something that we
absolutely have to do in order for the project or business to keep
operating &#8212; it&#8217;s more frustrating to find myself spending a large
amount of time on.

</p>
</div>

</div>

<div id="outline-container-1.3" class="outline-3">
<h3 id="sec-1.3">In conclusion </h3>
<div id="text-1.3">


<p>
I believe in code review as a powerful tool. But in practice, I&#8217;ve
found it frustrating to work with. I&#8217;d like to hear your thoughts:
Does code review work for you? Am I doing it wrong, in some ways? Is
it just a question of changing my attitude in some way?
</p>
<p>
I know that a lot has been written about doing code review
effectively. I&#8217;d appreciate pointers to anything you&#8217;ve found
particularly compelling.
</p></div>
</div>

<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/i-hate-code-review/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

