<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Digital Digressions by Stuart Sierra</title>
	
	<link>http://stuartsierra.com</link>
	<description>From programming to everything else</description>
	<lastBuildDate>Thu, 17 May 2012 14:46:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/StuartSierra" /><feedburner:info uri="stuartsierra" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Syntactic Pipelines</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/IIbLA2VqX98/syntactic-pipelines</link>
		<comments>http://stuartsierra.com/2012/05/16/syntactic-pipelines#comments</comments>
		<pubDate>Wed, 16 May 2012 22:42:41 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[macros]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=624</guid>
		<description><![CDATA[Lately I&#8217;ve been thinking about Clojure programs written in this &#8220;threaded&#8221; or &#8220;pipelined&#8221; style: (defn large-process [input] (-&#62; input subprocess-one subprocess-two subprocess-three)) If you saw my talk at Clojure/West (video forthcoming) this should look familiar. The value being &#8220;threaded&#8221; by &#8230; <a href="http://stuartsierra.com/2012/05/16/syntactic-pipelines">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
  .org-constant {
     color: purple;
  }</p>
<p>  .org-string {
     color: green;
  }</p>
<p>  .org-comment {
     color: darkred;
  }</p>
<p>  .org-comment-delimiter {
     color: darkred;
  }</p>
<p>  .org-keyword, .org-builtin, .org-variable-name {
     color: blue;
  }
  </style>
<p>
Lately I&#8217;ve been thinking about Clojure programs written in this &#8220;threaded&#8221; or &#8220;pipelined&#8221; style:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defn</span> <span class="org-function-name">large-process</span> [input]
  (<span class="org-builtin">-&gt;</span> input
      subprocess-one
      subprocess-two
      subprocess-three))
</pre>
<p>
If you saw my talk at Clojure/West (<a href="http://clojurewest.org/news/2012/5/11/clojurewest-video-schedule.html">video forthcoming</a>) this should look familiar. The value being &#8220;threaded&#8221; by the <code>-&gt;</code> macro from one <i>subprocess-</i> function to the next is usually a map, and each subprocess can add, remove, or update keys in the map. A typical subprocess function might look something like this:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defn</span> <span class="org-function-name">subprocess-two</span> [data]
  (<span class="org-builtin">let</span> [{<span class="org-constant">:keys</span> [alpha beta]} data]
    (<span class="org-builtin">-&gt;</span> data
        (<span class="org-variable-name">assoc</span> <span class="org-constant">:epsilon</span> (compute-epsilon alpha))
        (<span class="org-variable-name">update-in</span> [<span class="org-constant">:gamma</span>] merge (compute-gamma beta)))))
</pre>
<p>
Most subprocess functions, therefore, have a similar structure: they begin by destructuring the input map and end by performing updates to that same map.
</p>
<p>
This style of programming tends to produce slightly longer code than would be obtained by writing larger functions with <code>let</code> bindings for intermediate values, but it has some advantages. The structure is immediately apparent: someone reading the code can get a high-level overview of what the code does simply by looking at the outer-most function, which, due to the single-pass design of Clojure&#8217;s compiler, will always be at the bottom of a file. It&#8217;s also easy to insert new functions into the process: as long as they accept and return a map with the same structure, they will not interfere with the existing functions.
</p>
<p>
The only problem with this code from a readability standpoint is the visual clutter of repeatedly destructuring and updating the same map. (It&#8217;s possible to move the destructuring into the function argument vector, but it&#8217;s still messy.)
</p>
<div id="outline-container-1" class="outline-2">
<h2 id="sec-1">defpipe</h2>
<div class="outline-text-2" id="text-1">
<p>
What if we could clean up the syntax without changing the behavior? That&#8217;s exactly what macros are good for. Here&#8217;s a first attempt:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defmacro</span> <span class="org-function-name">defpipe</span> [name argv &amp; body]
  `(<span class="org-keyword">defn</span> <span class="org-function-name">~name</span> [arg#]
     (<span class="org-builtin">let</span> [{<span class="org-constant">:keys</span> ~argv} arg#]
       ~@body)))
</pre>
<pre class="src src-clojure">(<span class="org-variable-name">macroexpand-1</span> '(<span class="org-keyword">defpipe</span> <span class="org-function-name">foo</span> [a b c] ...))
<span class="org-comment-delimiter">;;</span><span class="org-comment">=&gt; (clojure.core/defn foo [arg_47_auto]</span>
<span class="org-comment-delimiter">;;     </span><span class="org-comment">(clojure.core/let [{:keys [a b c]} arg_47_auto] ...))</span>
</pre>
<p>
That doesn&#8217;t quite work: we&#8217;ve eliminated the <code>:keys</code> destructuring, but lost the original input map.
</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="sec-2">return</h2>
<div class="outline-text-2" id="text-2">
<p>
What if we make a second macro specifically for updating the input map?
</p>
<pre class="src src-clojure">(<span class="org-keyword">def</span> <span class="org-constant">^:private</span> <span class="org-function-name">pipe-arg</span> (<span class="org-variable-name">gensym</span> <span class="org-string">"pipeline-argument"</span>))

(<span class="org-keyword">defmacro</span> <span class="org-function-name">defpipe</span> [name argv &amp; body]
  `(<span class="org-keyword">defn</span> <span class="org-function-name">~name</span> [~pipe-arg]
     (<span class="org-builtin">let</span> [{<span class="org-constant">:keys</span> ~argv} ~pipe-arg]
       ~@body)))

(<span class="org-keyword">defn-</span> <span class="org-function-name">return-clause</span> [spec]
  (<span class="org-builtin">let</span> [[command sym &amp; body] spec]
    (<span class="org-builtin">case</span> command
      <span class="org-constant">:update</span> `(<span class="org-variable-name">update-in</span> [~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym))] ~@body)
      <span class="org-constant">:set</span>    `(<span class="org-variable-name">assoc</span> ~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym)) ~@body)
      <span class="org-constant">:remove</span> `(<span class="org-variable-name">dissoc</span> ~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym)) ~@body)
      body)))

(<span class="org-keyword">defmacro</span> <span class="org-function-name">return</span> [&amp; specs]
  `(<span class="org-builtin">-&gt;</span> ~pipe-arg
       ~@(<span class="org-variable-name">map</span> return-clause specs)))
</pre>
<p>
This requires some more explanation. The <code>return</code> macro works in tandem with <code>defpipe</code>, and provides a mini-language for threading the input map through a series of transformations. So it can be used like this:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defpipe</span> <span class="org-function-name">foo</span> [a b]
  (return (<span class="org-constant">:update</span> a + 10)
          (<span class="org-constant">:remove</span> b)
          (<span class="org-constant">:set</span> c a)))

<span class="org-comment-delimiter">;; </span><span class="org-comment">which expands to:</span>
(<span class="org-keyword">defn</span> <span class="org-function-name">foo</span> [input]
  (<span class="org-builtin">let</span> [{<span class="org-constant">:keys</span> [a b]} input]
    (<span class="org-builtin">-&gt;</span> input
        (<span class="org-variable-name">update-in</span> [<span class="org-constant">:a</span>] + 10)
        (<span class="org-variable-name">dissoc</span> <span class="org-constant">:b</span>)
        (<span class="org-variable-name">assoc</span> <span class="org-constant">:c</span> a))))
</pre>
<p>
As a fallback, we can put any old expression inside the <code>return</code>, and it will be just as if we had used it in the <code>-&gt;</code> macro. The rest of the code inside <code>defpipe</code>, before <code>return</code>, is a normal function body. The <code>return</code> can appear anywhere inside <code>defpipe</code>, as long as it is in tail position.
</p>
<p>
The symbol used for the input argument has to be the same in both <code>defpipe</code> and <code>return</code>, so we define it once and use it again. This is safe because that symbol is not exposed anywhere else, and the <code>gensym</code> ensures that it is unique.
</p>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="sec-3">defpipeline</h2>
<div class="outline-text-2" id="text-3">
<p>
Now that we have the <code>defpipe</code> macro, it&#8217;s trivial to add another macro for defining the composition of functions created with <code>defpipe</code>:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defmacro</span> <span class="org-function-name">defpipeline</span> [name &amp; body]
  `(<span class="org-keyword">defn</span> <span class="org-function-name">~name</span> [arg#]
     (<span class="org-builtin">-&gt;</span> arg# ~@body)))
</pre>
<p>
This macro does so little that I debated whether or not to include it. The only thing it eliminates is the argument name. But I like the way it expresses intent: a pipeline is purely the composition of <code>defpipe</code> functions.
</p>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="sec-4">Further Possibilities</h2>
<div class="outline-text-2" id="text-4">
<p>
One flaw in the &#8220;pipeline&#8221; style is that it cannot express conditional logic in the middle of a pipeline. Some might say this is a feature: the whole point of the pipeline is that it defines a single thread of execution. But I&#8217;m toying with the idea of adding syntax for predicate dispatch within a pipeline, something like this:
</p>
<pre class="src src-clojure">(<span class="org-keyword">defpipeline</span> <span class="org-function-name">name</span>
  pipe1
  <span class="org-comment-delimiter">;; </span><span class="org-comment">Map signifies a conditional branch:</span>
  {predicate-a pipe-a
   predicate-b pipe-b
   <span class="org-constant">:else</span>       pipe-c}
  <span class="org-comment-delimiter">;; </span><span class="org-comment">Regular pipeline execution follows:</span>
  pipe2
  pipe3)
</pre>
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h2 id="sec-5">The Whole Shebang</h2>
<div class="outline-text-2" id="text-5">
<p>
The complete implementation follows. I&#8217;ve added doc strings, metadata, and some helper functions to parse the arguments to <code>defpipe</code> and <code>defpipeline</code> in the same style as <code>defn</code>.
</p>
<pre class="src src-clojure">(<span class="org-keyword">def</span> <span class="org-constant">^:private</span> <span class="org-function-name">pipe-arg</span> (<span class="org-variable-name">gensym</span> <span class="org-string">"pipeline-argument"</span>))

(<span class="org-keyword">defn-</span> <span class="org-function-name">req</span>
  <span class="org-doc">"Required argument"</span>
  [pred spec message]
  (<span class="org-variable-name">assert</span> (pred (<span class="org-variable-name">first</span> spec))
          (<span class="org-variable-name">str</span> message <span class="org-string">" : "</span> (<span class="org-variable-name">pr-str</span> (<span class="org-variable-name">first</span> spec))))
  [(<span class="org-variable-name">first</span> spec) (<span class="org-variable-name">rest</span> spec)])

(<span class="org-keyword">defn-</span> <span class="org-function-name">opt</span>
  <span class="org-doc">"Optional argument"</span>
  [pred spec]
  (<span class="org-builtin">if</span> (pred (<span class="org-variable-name">first</span> spec))
    [(<span class="org-variable-name">list</span> (<span class="org-variable-name">first</span> spec)) (<span class="org-variable-name">rest</span> spec)]
    [nil spec]))

(<span class="org-keyword">defmacro</span> <span class="org-function-name">defpipeline</span> [name &amp; spec]
  (<span class="org-builtin">let</span> [[docstring spec] (opt string? spec)
        [attr-map spec] (opt map? spec)]
    `(<span class="org-keyword">defn</span> <span class="org-function-name">~name</span>
       ~@docstring
       ~@attr-map
       [arg#]
       (<span class="org-builtin">-&gt;</span> arg# ~@spec))))

(<span class="org-keyword">defmacro</span> <span class="org-function-name">defpipe</span>
  <span class="org-doc">"Defines a function which takes one argument, a map. The params are</span>
<span class="org-doc">  symbols, which will be bound to values from the map as by :keys</span>
<span class="org-doc">  destructuring. In any tail position of the body, use the 'return'</span>
<span class="org-doc">  macro to update and return the input map."</span>
  [name &amp; spec]
  {<span class="org-constant">:arglists</span> '([name doc-string? attr-map? [params*] &amp; body])}
  (<span class="org-builtin">let</span> [[docstring spec] (opt string? spec)
        [attr-map spec] (opt map? spec)
        [argv spec] (req vector? spec <span class="org-string">"Should be a vector"</span>)]
    (<span class="org-variable-name">assert</span> (<span class="org-variable-name">every?</span> symbol? argv)
            (<span class="org-variable-name">str</span> <span class="org-string">"Should be a vector of symbols : "</span>
                 (<span class="org-variable-name">pr-str</span> argv)))
    `(<span class="org-keyword">defn</span> <span class="org-function-name">~name</span>
       ~@docstring
       ~@attr-map
       [~pipe-arg]
       (<span class="org-builtin">let</span> [{<span class="org-constant">:keys</span> ~argv} ~pipe-arg]
         ~@spec))))

(<span class="org-keyword">defn-</span> <span class="org-function-name">return-clause</span> [spec]
  (<span class="org-builtin">let</span> [[command sym &amp; body] spec]
    (<span class="org-builtin">case</span> command
      <span class="org-constant">:update</span> `(<span class="org-variable-name">update-in</span> [~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym))] ~@body)
      <span class="org-constant">:set</span>    `(<span class="org-variable-name">assoc</span> ~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym)) ~@body)
      <span class="org-constant">:remove</span> `(<span class="org-variable-name">dissoc</span> ~(<span class="org-variable-name">keyword</span> (<span class="org-variable-name">name</span> sym)) ~@body)
      body)))

(<span class="org-keyword">defmacro</span> <span class="org-function-name">return</span>
  <span class="org-doc">"Within the body of the defpipe macro, returns the input argument of</span>
<span class="org-doc">  the defpipe function. Must be in tail position. The input argument,</span>
<span class="org-doc">  a map, is threaded through exprs as by the -&gt; macro.</span>

<span class="org-doc">  Expressions within the 'return' macro may take one of the following</span>
<span class="org-doc">  forms:</span>

<span class="org-doc">      (:set key value)      ; like (assoc :key value)</span>
<span class="org-doc">      (:remove key)         ; like (dissoc :key)</span>
<span class="org-doc">      (:update key f args*) ; like (update-in [:key] f args*)</span>

<span class="org-doc">  Optionally, any other expression may be used: the input map will be</span>
<span class="org-doc">  inserted as its first argument."</span>
  [&amp; exprs]
  `(<span class="org-builtin">-&gt;</span> ~pipe-arg
       ~@(<span class="org-variable-name">map</span> return-clause exprs)))
</pre>
</div>
</div>
<div id="outline-container-6" class="outline-2">
<h2 id="sec-6">And a Made-Up Example</h2>
<div class="outline-text-2" id="text-6">
<pre class="src src-clojure">(<span class="org-keyword">defpipe</span> <span class="org-function-name">setup</span> []
  (return  <span class="org-comment-delimiter">; </span><span class="org-comment">imagine these come from a database</span>
   (<span class="org-constant">:set</span> alpha 4)
   (<span class="org-constant">:set</span> beta 3)))

(<span class="org-keyword">defpipe</span> <span class="org-function-name">compute-step1</span> [alpha beta]
  (return (<span class="org-variable-name">:set</span> delta (<span class="org-variable-name">+</span> alpha beta))))

(<span class="org-keyword">defpipe</span> <span class="org-function-name">compute-step2</span> [delta]
  (return
   (<span class="org-variable-name">assoc-in</span> [<span class="org-constant">:x</span> <span class="org-constant">:y</span>] 42)  <span class="org-comment-delimiter">; </span><span class="org-comment">ordinary function expression</span>
   (<span class="org-constant">:update</span> delta * 2)
   (<span class="org-constant">:set</span> gamma (<span class="org-variable-name">+</span> delta 100))))  <span class="org-comment-delimiter">; </span><span class="org-comment">uses old value of delta</span>

(<span class="org-keyword">defpipe</span> <span class="org-function-name">respond</span> [alpha beta gamma delta]
  (<span class="org-variable-name">println</span> <span class="org-string">" Alpha is"</span> alpha <span class="org-string">"\n"</span>
           <span class="org-string">"Beta is"</span> beta <span class="org-string">"\n"</span>
           <span class="org-string">"Delta is"</span> delta <span class="org-string">"\n"</span>
           <span class="org-string">"Gamma is"</span> gamma)
  (return)) <span class="org-comment-delimiter">; </span><span class="org-comment">not strictly necessary, but a good idea</span>

(<span class="org-keyword">defpipeline</span> <span class="org-function-name">compute</span>
  compute-step1
  compute-step2)

(<span class="org-keyword">defpipeline</span> <span class="org-function-name">process-request</span>
  setup
  compute
  respond)
</pre>
<pre class="src src-clojure">(process-request {})

<span class="org-comment-delimiter">;; </span><span class="org-comment">Alpha is 4 </span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">Beta is 3 </span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">Delta is 14 </span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">Gamma is 107</span>

<span class="org-comment-delimiter">;;</span><span class="org-comment">=&gt; {:gamma 107, :delta 14, :beta 3, :alpha 4}</span>
</pre>
</div>
</div>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/IIbLA2VqX98" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2012/05/16/syntactic-pipelines/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2012/05/16/syntactic-pipelines</feedburner:origLink></item>
		<item>
		<title>Three Kinds of Error</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/t9bF3DF1opA/three-kinds-of-error</link>
		<comments>http://stuartsierra.com/2012/04/03/three-kinds-of-error#comments</comments>
		<pubDate>Tue, 03 Apr 2012 16:07:00 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[exceptions]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=613</guid>
		<description><![CDATA[Warning! This post contains strong, New York City-inflected language. If you are discomfited or offended by such language, do not read further &#8230; further &#8230; further &#8230; further &#8230; This is about three categories of software error. I have given &#8230; <a href="http://stuartsierra.com/2012/04/03/three-kinds-of-error">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
<b>Warning! This post contains strong, New York City-inflected language. If you are discomfited or offended by such language, do not read further &hellip;</b>
</p>
<p>
further &hellip;
</p>
<p>
further &hellip;
</p>
<p>
further &hellip;
</p>
<p>
This is about three categories of software error. I have given them catchy names for purposes of illustration. The three kinds of error are the <i>Fuck-Up</i>, the <i>Oh, Fuck</i> and the <i>What the Fuck?</i>.
</p>
<div id="outline-container-1" class="outline-2">
<h2 id="sec-1">One</h2>
<div class="outline-text-2" id="text-1">
<p>
The <i>Fuck-Up</i> is a simple programmer mistake. In prose writing, it would be called a typo. You misspelled the name of a function or variable. You forgot to include all the arguments to a function. You misplaced a comma, bracket, or semicolon.
</p>
<p>
<i>Fuck-Up</i> errors are usually caught early in the development process and very soon after they are written. You made a change, and suddenly your program doesn&#8217;t work. You look back at what you just wrote and the mistake jumps right out at you.
</p>
<p>
Statically-typed languages can often catch <i>Fuck-Ups</i> at compile time, but not always. The mistake may be syntactically valid but semantically incorrect, or it may be a literal value such as a string or number which is not checked by the compiler. I find that one of the more insidious <i>Fuck-Ups</i> occurs when I misspell the name of a field, property, or keyword. This is more common in dynamically-typed languages that use literal keywords for property accesses, but even strongly-typed Java APIs sometimes use strings for property names. Compile-time type checkers cannot save you from all your <i>Fuck-Ups</i>.
</p>
<p>
I&#8217;ve occasionally wished for a source code checker that would look at all syntactic tokens in my program and warn me whenever I use a token exactly once: that&#8217;s a good candidate for a typo. Editors can help: even without the kind of semantic auto-completion found in Java IDEs, I&#8217;ve found I can avoid some misspellings by using auto-completion based solely on other text in the project.
</p>
<p>
<i>Fuck-Ups</i> become harder to diagnose the longer they go unnoticed. They are particularly dangerous in edge-case code that rarely gets run. The application seems to work until it encounters that unusual path, at which point it fails mysteriously. The failure could be many layers removed from the source line containing the <i>Fuck-Up</i>. This is where rapid feedback cycles and test coverage are helpful.
</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="sec-2">Two</h2>
<div class="outline-text-2" id="text-2">
<p>
Said with a mixture of resignation and annoyance, <i>Oh, Fuck</i> names the category of error when a program makes a seemingly-reasonable assumption about the state of the world that turns out not to be true. A file doesn&#8217;t exist. There isn&#8217;t enough disk space. The network is unreachable. We have wandered off the happy path and stumbled into the wilderness of the unexpected.
</p>
<p>
<i>Oh, Fuck</i> errors are probably the most common kind to make it past tests, due to positive bias. They&#8217;re also the most commonly ignored during development, because they are essentially unrelated to the problem at hand. You don&#8217;t care <i>why</i> the file wasn&#8217;t there, and it&#8217;s not necessarily something you can do anything about. But your code still has to deal with the possibility.
</p>
<p>
I would venture that most errors which make it through static typing, testing, and QA to surface in front of production users are <i>Oh, Fuck</i> errors. It&#8217;s difficult to anticipate everything that could go wrong.
</p>
<p>
However, I believe that <i>Oh, Fuck</i> errors are often inappropriately categorized as exceptions, because they are not really &#8220;exceptional,&#8221; <i>i.e.</i> rare. Exceptions are a form of non-local control flow, the last relic of <code>GOTO</code>. Whenever a failed condition causes an <i>Oh, Fuck</i> error, it typically needs to be handled locally, near the code that attempted to act on the condition, not in some distant error handler. Java APIs frequently use exceptions to indicate that an operation failed, but really they&#8217;re working around Java&#8217;s lack of union types. The return type of an file-read operation, for example, is the union of its normal return value and <code>IOException</code>. You have to handle both cases, but there&#8217;s rarely a good reason for the <code>IOException</code> to jump all the way out of the current function stack.
</p>
<p>
Programming &#8220;defensively&#8221; is not a bad idea, but filling every function with try/catch clauses is tedious and clutters up the code with non-essential concerns. I would advocate, instead, trying to isolate problem-domain code behind a &#8220;defensive&#8221; barrier of condition checking. Enumerate all the assumptions your code depends on, then encapsulate it in code which checks those assumptions. Then the problem-domain code can remain concise and free of extraneous error-checking.
</p>
<p>
Java APIs also frequently use <code>null</code> return values to indicate failure. Every non-primitive Java type declaration is an implicit union with <code>null</code>, but it&#8217;s easy to forget this, leading to the dreaded and difficult-to-diagnose <code>NullPointerException</code>. The possibility of a <code>null</code> return value really should be part of the type declaration. For languages which do not support such declarations, rigorous documentation is the only recourse.
</p>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="sec-3">Three</h2>
<div class="outline-text-2" id="text-3">
<p>
Finally, we have the errors that really are exceptional circumstances. You ran out of memory, divided by zero, overflowed an integer. In rare cases, these errors are caused by intermittent hardware failures, making them virtually impossible to reproduce consistently. More commonly, they are caused by emergent properties of the code that you did not anticipate. <i>What the Fuck?</i> errors are almost always encountered in production, when the program is exposed to new circumstances, longer runtimes, or heavier loads than it was ever tested with.
</p>
<p>
By definition, <i>What the Fuck?</i> errors are those you did not expect. The best you can do is try to ensure that such errors are noticed quickly and are not allowed to compromise the correct behavior of the system. Depending on requirements, this may mean the system should immediately shut down on encountering such an error, or it may mean selectively aborting and restarting the affected sub-processes. In either case, non-local control flow is probably your best hope. <i>What the Fuck?</i> errors are a crisis in your code: forget whatever you were trying to do and concentrate on minimizing the damage. The <i>worst</i> response is to ignore the error and continue as if nothing had happened: the system is in a failed state, and nothing it produces can be trusted.
</p>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="sec-4">Conclusion</h2>
<div class="outline-text-2" id="text-4">
<p>
All errors, even <i>What the Fuck?</i> errors, are ultimately programmer errors. But programmers are human, and software is hard. These categories I&#8217;ve named are not the only kinds of errors software can have, nor are they mutually exclusive. What starts as a simple <i>Fuck-Up</i> could trigger an <i>Oh, Fuck</i> that blossoms into a full-blown <i>What the Fuck?</i>.
</p>
<p>
Be careful out there.
</p>
</div>
</div>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/t9bF3DF1opA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2012/04/03/three-kinds-of-error/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2012/04/03/three-kinds-of-error</feedburner:origLink></item>
		<item>
		<title>Clojure 2011 Year in Review</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/U3JOUjR6Ufw/clojure-2011-year-in-review</link>
		<comments>http://stuartsierra.com/2012/01/03/clojure-2011-year-in-review#comments</comments>
		<pubDate>Tue, 03 Jan 2012 13:00:15 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=607</guid>
		<description><![CDATA[A new year is upon us. Before the world ends, let&#8217;s take a look back at what 2011 meant for everybody&#8217;s favorite programming language: Clojure 1.3.0 was released, bringing better performance to numeric applications, reader syntax for record types, and &#8230; <a href="http://stuartsierra.com/2012/01/03/clojure-2011-year-in-review">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A new year is upon us. Before the world ends, let&#8217;s take a look back at what 2011 meant for everybody&#8217;s favorite programming language:
</p>
<ul>
<li>
<p><a href="https://groups.google.com/d/msg/clojure/w5Nmx5rPaQs/-Kl4dvGApP0J">Clojure 1.3.0 was released</a>, bringing better performance to numeric applications, reader syntax for record types, and <a href="https://github.com/clojure/clojure/blob/1.3.x/changes.txt">other enhancements</a>.</p>
</li>
<li>
<p><a href="http://clojure.com/blog/2011/07/22/introducing-clojurescript.html">ClojureScript was unveiled</a> to the world, leading to universal confusion about how to pronounce &#8220;Clojure&#8221; differently from &#8220;Closure.&#8221;</p>
</li>
<li>
<p>The <a href="http://clojure-conj.org/">second Clojure/conj</a> went off without a hitch but <a href="http://overtone.github.com/">plenty of bang</a>.</p>
</li>
<li>
<p><a href="http://clojure.com/blog/2011/12/05/lojic-part-one.html">Logic programming</a> burst into the mindspace of Clojure developers with <a href="http://clojure.com/blog/2011/12/08/lojic-part-two.html">core.logic</a>.</p>
</li>
<li>
<p><a href="http://dev.clojure.org/display/doc/Clojure+Contrib">Clojure-contrib was completely restructured</a> to support new libraries, a distributed development model, and an automated release process.</p>
</li>
<li>
<p><a href="https://groups.google.com/d/msg/clojure/QZGmfWFsgoo/XbqpUy5wuqYJ">ClojureCLR got a new home</a> and recognition as a Clojure sub-project.</p>
</li>
<li>
<p>David Liebke <a href="http://clojure.com/blog/2011/11/29/avout.html">introduced Avout</a>, an extension of Clojure&#8217;s software transactional memory model to distributed computing.</p>
</li>
<li>
<p>Clojure project management tools <a href="http://groups.google.com/group/leiningen/browse_thread/thread/5a79d02198a91b91">Leiningen and Cake</a> decided to bury the hatchet and join forces for the greater good.</p>
</li>
<li>
<p><a href="http://clojure.com/blog/">Clojure/core started blogging</a> more regularly.</p>
</li>
<li>
<p>Books! <a href="http://www.manning.com/fogus/">The Joy of Clojure</a> and <a href="http://www.manning.com/rathore/">Clojure in Action</a> (both from Manning) hit the bookshelves. The <a href="http://pragprog.com/book/shcloj2/programming-clojure">Second Edition of Programming Clojure</a> (Pragmatic) and <a href="http://shop.oreilly.com/product/0636920013754.do">Clojure Programming</a> (O&#8217;Reilly) went into early release.</p>
</li>
<li>
<p>PragPub magazine <a href="http://pragprog.com/magazines/2011-07/content">dedicated their July 2011 issue to Clojure</a>.</p>
</li>
<li>
<p>Chas Emerick released <a href="http://www.clojureatlas.com/">Clojure Atlas</a>, an interactive documentation system.</p>
</li>
<li>
<p>Clojure creator <a href="http://www.infoq.com/presentations/Simple-Made-Easy">Rich Hickey spoke at Strange Loop</a> and caused a minor tweet-storm.</p>
</li>
<li>
<p><a href="https://www.4clojure.com/">4Clojure</a> entered the world, giving thousands of programmers a new way to kill time and learn Clojure.</p>
</li>
</ul>
<p>
At this point, I&#8217;ve been typing and looking up links for an hour, so I&#8217;m calling it quits. Needless to say, this was a big year for Clojure, and I&#8217;m sure there&#8217;s a ton of stuff that I missed on this list. Regarding 2012, all I can say is, <i>You ain&#8217;t seen nothing yet</i>.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/U3JOUjR6Ufw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2012/01/03/clojure-2011-year-in-review/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2012/01/03/clojure-2011-year-in-review</feedburner:origLink></item>
		<item>
		<title>A Hacker’s Christmas Song</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/P_oG0D-pQaU/a-hackers-christmas-song</link>
		<comments>http://stuartsierra.com/2011/12/24/a-hackers-christmas-song#comments</comments>
		<pubDate>Sat, 24 Dec 2011 15:54:06 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=599</guid>
		<description><![CDATA[I&#8217;ll be home for Christmas To fix your old PC. Please have Coke and Mountain Dew And pizza there for me. Christmas Eve will find me In Windows Update screens, I&#8217;ll be done by New Year&#8217;s If only in my &#8230; <a href="http://stuartsierra.com/2011/12/24/a-hackers-christmas-song">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be home for Christmas<br />
To fix your old PC.<br />
Please have Coke and Mountain Dew<br />
And pizza there for me.</p>
<p>Christmas Eve will find me<br />
In Windows Update screens,<br />
I&#8217;ll be done by New Year&#8217;s<br />
If only in my dreams.</p>
<p>I&#8217;ll be home for Christmas<br />
Installing Google Chrome,<br />
Removing malware, cruft, and crud,<br />
And backing up your /home.</p>
<p>Christmas Eve will find me<br />
Swearing at the screen,<br />
Replacing it with Linux<br />
If only in my dreams.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/P_oG0D-pQaU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/12/24/a-hackers-christmas-song/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/12/24/a-hackers-christmas-song</feedburner:origLink></item>
		<item>
		<title>What Is a Program?</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/K6zN9Qvi2E4/what-is-a-program</link>
		<comments>http://stuartsierra.com/2011/12/19/what-is-a-program#comments</comments>
		<pubDate>Mon, 19 Dec 2011 13:45:08 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[metaprogramming]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=589</guid>
		<description><![CDATA[What is a program? Is it the source code that a programmer typed? The physical state of the machine on which it is run? Or something more abstract, like the data structures it creates? This is not a purely philosophical &#8230; <a href="http://stuartsierra.com/2011/12/19/what-is-a-program">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What is a program? Is it the source code that a programmer typed? The physical state of the machine on which it is run? Or something more abstract, like the data structures it creates? This is not a purely philosophical question: it has consequences for how programming languages are designed, how development tools work, and what programmers do when we go to work every day.</p>
<p>How much information can we determine about a program <em>without</em> evaluating it? At the high end, we have the Halting Problem: for any Turing-complete programming language, we cannot determine if a given program written in that language will terminate. At the low end, consider an easier problem: can we determine the names of all of the invokable functions/procedures/methods in a given program? In a language in which functions are not first-class entities, such as C or Java, this is generally easy, because every function must have a specific lexical representation in source code. If we can parse the source code, we can find all the functions. At the other extreme, finding all function names in a language like Ruby is nearly impossible in the face of <code>method_missing</code>, <code>define_method</code>, and other &#8220;metaprogramming&#8221; tricks.</p>
<p>Again, these decisions have consequences. Ruby code is flexible and concise, but it&#8217;s hard to parse: <a href="https://github.com/ruby/ruby/blob/ruby_1_9_2/parse.y">ten thousand lines of YACC at last count</a>. I find that documentation generated from Ruby source code tends to be harder to read &mdash; and less useful &mdash; than JavaDoc. </p>
<p>Here&#8217;s another example: can I determine, without evaluating it, what other functions a given function calls? In Java this is easy. In C it&#8217;s much harder, because of the preprocessor. To build a complete call graph of a C function, we need to run the preprocessor first, in effect evaluating some of the code. In Ruby &mdash; Ha! Looking at a random piece of Ruby code, I sometimes have trouble distinguishing method calls from local variables. Again because of <code>method_missing</code>, I&#8217;m not sure it&#8217;s even possible to distinguish the two without evaluating the code.</p>
<p>I do not want to argue that <code>method_missing</code>, macros, and other metaprogramming tools in programming languages are bad. But they do make secondary tooling harder. The idea for this blog post came into my head after observing the following Twitter conversation:</p>
<blockquote>
<p><a href="https://twitter.com/#!/darevay/status/148235645083594753">Dave Ray</a>: &#8220;seesaw.core is 3500 lines of which probably 2500 are docstrings. I wonder if they could be externalized somehow&#8230;&#8221;</p>
<p><a href="https://twitter.com/#!/cemerick/status/148428056082649088">Chas Emerick</a>: &#8220;Put your docs in another file you load at the *end* of seesaw.core, w/ a bunch of <code>(alter-meta! #'f assoc :doc "docs")</code> exprs&#8221;</p>
<p><a href="https://twitter.com/#!/IORayne/status/148506007188946945">Anthony Grimes</a>: &#8220;I hate both of your guts for even thinking about doing this.&#8221;</p>
<p><a href="https://twitter.com/#!/cemerick/status/148519643101933568">Chas Emerick</a>: &#8220;Oh! [Anthony] is miffed b/c Marginalia doesn&#8217;t load namespaces it&#8217;s generating docs for. What was the rationale for that?&#8221;</p>
<p><a href="https://twitter.com/#!/fogus/status/148522300252237824">Michael Fogus</a>: &#8220;patches welcomed.&#8221;</p>
<p><a href="https://twitter.com/#!/cemerick/status/148522784451076098">Chas Emerick</a>: &#8220;Heh, sure. I&#8217;m just wondering if avoiding loading was intentional, i.e. in case someone has a (launch-missiles) top-level.&#8221;</p>
</blockquote>
<p>(As an aside, it&#8217;s hard to link to a Twitter conversation instead of individual tweets.)</p>
<p>Clojure &mdash; or any Lisp, really &mdash; exemplifies a tension between tools that operate on source code and tools that operate on the running state of a program. For any code-analysis task one might want to automate in Clojure, there are two possible approaches. One is to <code>read</code> the source as a sequence of data structures and analyze it. After all, in a Lisp, code is data. The other approach is to <code>eval</code> the source and analyze the state it generates.</p>
<p>For example, suppose I wanted to determine the names of all invokable functions in a Clojure program. I could write a program that scanned the source looking for forms beginning with <code>defn</code>, or I could evaluate the code and use introspection functions to search for all Vars in all namespaces whose values are functions. Which method is &#8220;correct&#8221; depends on the goal. </p>
<p>Michael Fogus wrote <a href="http://fogus.me/fun/marginalia/">Marginalia</a>, a documentation tool for Clojure which takes the first approach. Marginalia was inspired by Literate Programming, which advocates writing source code as a human-readable document, so the unevaluated &#8220;text&#8221; of the program is what it deals with. In contrast, Tom Faulhaber&#8217;s <a href="http://tomfaulhaber.github.com/autodoc/">Autodoc</a> for Clojure takes the second approach: loading code and then examining namespaces and Vars. Autodoc <em>has</em> to work this way to produce documentation for the core Clojure API: many functions in <code>core.clj</code> are defined before documentation strings are available, so their doc strings are loaded later from separate files. (As an alternative, those core functions could be rewritten in standard syntax after the language has been bootstrapped.)</p>
<p>One of the talking-point features of any Lisp is &#8220;all of the language, all of the time.&#8221; All features of the language are always available in any context: macros give access to the entire runtime of the language at compile time, and <code>eval</code> gives access to the entire compiler at runtime. These are a powerful tools for developers, but they make both the compiler and the runtime more complicated. ClojureScript, on the other hand, does not have <code>eval</code> and its macros are written in a different language (Clojure). These choices were deliberate because ClojureScript was designed to be compiled into compressed JavaScript to run on resource-constrained platforms, but I think it also made the ClojureScript compiler easier to write.</p>
<p>Chas&#8217;s last point about code at the top-level comes up often in discussions around Clojure tooling. The fact that we can write arbitrary code anywhere in a Clojure source file &mdash; <code>launch-missiles</code> being the popular example &mdash; means we can never be sure that evaluating a source file is free of side effects. But <em>not</em> evaluating the source means we can never be sure that we have an accurate model of what the code does. Welcome back to the Halting Problem.</p>
<p>Furthermore, maintaining all the metadata associated with a dynamic runtime &mdash; namespaces, Vars, doc strings, etc. &mdash; has measurable costs in performance and (especially) memory. If Clojure is ever to be successful on resource-constrained devices like phones, it will need the ability to produce compiled code that omits most or all of that metadata. At the same time, developers accustomed to the &#8220;creature comforts&#8221; of modern IDEs will continue to clamor for even more metadata. Fortunately, this isn&#8217;t a zero-sum game. ClojureScript proves that Clojure-the-language can work without some of those features, and there have been discussions around <a href="http://dev.clojure.org/display/design/Make+the+ClojureScript+analyzer+independently+callable+a+la+carte">making the ClojureScript analyzer more general</a> and implementing <a href="http://dev.clojure.org/display/design/Build+Profiles">targeted build profiles for Clojure</a>. But I don&#8217;t think we&#8217;ll ever have a perfect resolution of the conflict between tooling and optimization. Programs are ideas, and source code is only one representation among many. To understand a program, one needs to build a mental representation of how it operates. And to do that we&#8217;re stuck with the oldest tool we have, our brains.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/K6zN9Qvi2E4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/12/19/what-is-a-program/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/12/19/what-is-a-program</feedburner:origLink></item>
		<item>
		<title>JDK Version Survey Results</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/Xww4uEvC4uY/jdk-version-survey-results</link>
		<comments>http://stuartsierra.com/2011/11/04/jdk-version-survey-results#comments</comments>
		<pubDate>Fri, 04 Nov 2011 13:52:14 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=581</guid>
		<description><![CDATA[After a month and about 175 responses, here are the results of my JDK Version Usage Survey (now closed): Versions: Almost everyone uses 1.6. A few are still using 1.5, and a few are trying out 1.7. Only a handful &#8230; <a href="http://stuartsierra.com/2011/11/04/jdk-version-survey-results">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After a month and about 175 responses, here are the results of my JDK Version Usage Survey (now closed):</p>
<p><strong>Versions:</strong> Almost everyone uses 1.6. A few are still using 1.5, and a few are trying out 1.7. Only a handful are still on 1.4. Fortunately, no one is on a version older than 1.4.</p>
<p><a href="http://stuartsierra.com/wp-content/uploads/2011/11/2011-10-jdk-survey-versions.png"><img class="alignnone size-full wp-image-582" title="2011 JDK Version Survey: version results" src="http://stuartsierra.com/wp-content/uploads/2011/11/2011-10-jdk-survey-versions.png" alt="" width="651" height="243" /></a></p>
<p><strong>Reasons:</strong> These are more varied. The most common reason for not upgrading is lack of time, with &#8220;it just works&#8221; running a close second. A little less than half of respondents are limited by external forces: either operations/management or third-party dependencies.</p>
<p><a href="http://stuartsierra.com/wp-content/uploads/2011/11/2011-10-jdk-survey-reasons.png"><img src="http://stuartsierra.com/wp-content/uploads/2011/11/2011-10-jdk-survey-reasons.png" alt="" title="2011 JDK Versions Survey: reason responses" width="812" height="266" class="alignnone size-full wp-image-583" /></a></p>
<p>Not much came out in the comments. Banks and other large institutions seem to be the most resistant to upgrades, especially if they&#8217;ve been bitten by past JDK changes.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/Xww4uEvC4uY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/11/04/jdk-version-survey-results/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/11/04/jdk-version-survey-results</feedburner:origLink></item>
		<item>
		<title>JDK Version Survey</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/KzdziAfWg2U/jdk-version-survey</link>
		<comments>http://stuartsierra.com/2011/10/04/jdk-version-survey#comments</comments>
		<pubDate>Tue, 04 Oct 2011 12:52:05 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=575</guid>
		<description><![CDATA[The most recent JDK version poll I could find was from 2008 (thanks, Alex!) so here&#8217;s a new one. Loading&#8230;]]></description>
			<content:encoded><![CDATA[<p>The most recent JDK version poll I could find was <a href="http://java.dzone.com/news/jdk-version-poll-results">from 2008</a> (thanks, Alex!) so here&#8217;s a new one.</p>
<p><iframe src="https://docs.google.com/spreadsheet/embeddedform?formkey=dEU5a0d1VE52NFhOQTJUblFKUmVKeWc6MQ" width="760" height="870" frameborder="0" marginheight="0" marginwidth="0">Loading&#8230;</iframe></p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/KzdziAfWg2U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/10/04/jdk-version-survey/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/10/04/jdk-version-survey</feedburner:origLink></item>
		<item>
		<title>Design Philosophies of Developer Tools</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/FoqySOfivHo/design-philosophies-of-developer-tools</link>
		<comments>http://stuartsierra.com/2011/08/30/design-philosophies-of-developer-tools#comments</comments>
		<pubDate>Wed, 31 Aug 2011 00:55:15 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=565</guid>
		<description><![CDATA[I&#8217;ve been thinking about some of the tools that I use every day, and about the different design philosophies they reflect. Git First and foremost, Git. We use Git on every single project, internal and external. Git is a great &#8230; <a href="http://stuartsierra.com/2011/08/30/design-philosophies-of-developer-tools">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking about some of the tools that I use every day, and about the different design philosophies they reflect.</p>
<h3>Git</h3>
<p>First and foremost, Git. <a href="http://thinkrelevance.com/">We</a> use Git on every single project, internal and external. Git is a great example of the Unix design philosophy: many small programs &mdash; 153 of them by my count &mdash; each of which does exactly one thing and does it well. But this is not &#8220;loose coupling.&#8221; The components of Git are tightly integrated: they all depend on the same <a href="http://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html">repository structure</a> and file formats. </p>
<p>One of the nice things about Git is how its internals are both exposed for the world to see and thoroughly documented. We can easily write scripts to automate common tasks or create different workflows. With a bit more effort, we could even write new tools that integrate with the Git suite. These tools can do things that Git&#8217;s authors never intended, as long as they follow the documented repository structure. Git isn&#8217;t so much a version control system as the means to construct one.</p>
<p>Still, Git is one project with many components, not many separate projects. All 153 executables in Git are governed by a single release cycle, tested and known to work together. We never have to worry about incompatible versions of, say, <code>git-branch</code> and <code>git-merge</code> on the same machine. Older versions of Git can read repositories created with newer versions even if they don&#8217;t provide all the same features.</p>
<h3>Maven</h3>
<p>In stark contrast to Git, we have tools from the Java world like <a href="http://ant.apache.org/">Ant</a> and <a href="http://maven.apache.org/">Maven</a>. The <a href="http://blog.headius.com/2009/05/fork-and-exec-on-jvm-jruby-to-rescue.html">JVM cannot fork/exec</a>, so the many-small-programs design is a non-starter. Instead, the Java tools usually favor some sort of plug-in architecture, which is a great idea in theory but hard to get right in practice. </p>
<p>I&#8217;ve <a href="https://github.com/stuartsierra/new-clojure-maven-plugin">tried writing a Maven plugin</a>. Hacking up a one-off for a single project is not too difficult, but designing a general-purpose plugin that works everywhere is maddeningly complicated. Maven plugins are just Java code, so they can do whatever they want, but the APIs for interacting with the rest of the Maven system are woefully underdocumented. The <strong>contract</strong> of a Maven plugin, what it can and cannot do, is not well-defined. The internals of Maven itself are largely a black box. </p>
<p>The core Maven plug-ins have independent release cycles, so there is the possibility for unexpected incompatibilities, but I&#8217;ve never encountered such. On the whole, the Maven ecosystem is quite stable. The struggle comes once you venture outside the realm of what the standard plugins provide. Maven plugins are not designed to be composed, so adding new capabilities is rarely as simple as scripting plugins that already exist. You have to start from scratch every time.</p>
<h3>Ruby / Rubygems / RVM / Bundler</h3>
<p>Finally, we have tools from the Ruby world, the ever-changing cornucopia of Ruby implementations, libraries, and tools to manage it all. The problem with the Ruby tools is that they are both tightly-coupled and uncoordinated. Despite having separate tools for each task, each tool reaches into at least one of the others: Rubygems modifies the behavior of the Ruby interpreter, Bundler modifies the behavior of Rubygems, RVM modifies the behavior of the <em>shell</em>, and so on. Each one adds another layer of indirection, making debugging harder.</p>
<p>All of the Ruby development tools have independent release cycles, and they don&#8217;t seem to plan or coordinate with one another in advance of each release. Integration testing is left up to the users.</p>
<p>I admire the speed and eagerness with which the Ruby community produces new tools. But on almost every Ruby project I&#8217;ve worked on, we&#8217;ve spent hours or days sorting out incompatibilities among some combination of libraries, language implementations, and development tools.  Our internal mailing list is littered with advice like &#8220;Don&#8217;t use Bundler version X with RVM version Y.&#8221; The speed of development comes with its own cost.</p>
<h3>Thoughts</h3>
<p>So what do I take from all this? Just a few principles to keep in mind when writing software tools:</p>
<ol>
<li>Plan for integration</li>
<li>Rigorously specify the boundaries and extension points of your system</li>
<li>Do not depend on unspecified behavior</li>
</ol>
<p>And a couple of ideas if you&#8217;re starting a new project from scratch:</p>
<ol>
<li>The filesystem is the universal integration point</li>
<li>Fork/exec is the universal plugin architecture</li>
</ol>
<p><strong>Update 8/31:</strong> More comments at <a href="http://news.ycombinator.com/item?id=2943902">Hacker News</a>.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/FoqySOfivHo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/08/30/design-philosophies-of-developer-tools/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/08/30/design-philosophies-of-developer-tools</feedburner:origLink></item>
		<item>
		<title>The Naming of Namespaces</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/iwwS36YzFcU/clojure-namespaces</link>
		<comments>http://stuartsierra.com/2011/08/08/clojure-namespaces#comments</comments>
		<pubDate>Tue, 09 Aug 2011 01:43:58 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=550</guid>
		<description><![CDATA[From time to time I&#8217;m asked, &#8220;How do you organize namespaces in Clojure projects?&#8221; The question surprised me at first, because I hadn&#8217;t thought about it much. But then I was using Clojure back when the only way to load &#8230; <a href="http://stuartsierra.com/2011/08/08/clojure-namespaces">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>From time to time I&#8217;m asked, &#8220;How do you organize namespaces in Clojure projects?&#8221; The question surprised me at first, because I hadn&#8217;t thought about it much. But then I was using Clojure <a href="http://xkcd.com/378/">back when</a> the only way to load code was &#8220;load-file.&#8221;</p>
<p>Most programming languages, especially object-oriented languages, provide strong hints on how to structure your source files. Everything is a class, and (almost) every class is a file. In Clojure, everything (almost) is a function. Functions are much smaller units than classes. So how do we group them?</p>
<p>The important thing to remember about namespaces is that, from the compiler&#8217;s point of view, they don&#8217;t matter. Namespaces are a convenience for the programmer, to help you avoid name clashes without having to write longer names. There&#8217;s no reason why an entire application can&#8217;t be defined in a single namespace. Most of Clojure itself is defined in <a href="http://clojure.github.com/clojure/#clojure.core">one namespace</a> with over 500 symbols. (Common Lisp has <a href="http://www.lispworks.com/documentation/HyperSpec/Front/X_Symbol.htm">978 symbols</a> in a single namespace.)</p>
<p>You can think of namespaces as a tool to <strong>express something</strong> about your application. Here are some ideas to get you started:</p>
<ul>
<li>Group functions into namespaces based on <strong>type of data</strong> they manipulate. For example, functions to manipulate customer data go in the &#8220;customer&#8221; namespace. This technique is familiar from object-oriented languages, but it has the same limitations: where do you put functions concerning relationships among two or more types? The OO answer would be to make a new name for the relationship. This style leads to a proliferation of small namespaces, which can become a burden.</li>
<li>Divide a library into a <strong>public API</strong> namespace and a <strong>internal implementation</strong> namespace. Or define a <strong>high-level API</strong> for common cases and a <strong>low-level API</strong> for more advanced usage.</li>
<li>Divide an application into namespaces representing <strong>architectural layers</strong>. You can examine &#8220;ns&#8221; declarations to prove that each layer calls functions only from the layer below it.</li>
<li>Divide an application into namespaces representing <strong>functional modules</strong>, with well-defined contracts for communication between modules.</li>
<li>Try to separate <strong>decision-making</strong> code from the code that <strong>carries out</strong> those decisions. That is, keep your business logic purely functional and free of side-effects, so it is easy to test. You don&#8217;t necessarily have to put side-effect code in a separate namespace, but doing so may help keep it cleanly separated.</li>
</ul>
<p>With all these techniques, the point to remember is that namespaces are there to help you, not to get in your way. If you have a large namespace, you can still divide it up into multiple files.</p>
<p>The one hard-and-fast rule is that you cannot have a circular dependency between namespaces. That is, if namespace A needs to call functions defined in namespace B, then namespace B <strong>cannot</strong> call functions in namespace A. There is no workaround, it simply can&#8217;t be done. In practice, this is rarely a problem. If you encounter a situation where two namespaces are mutually dependent, it&#8217;s probably a sign that they should be merged into a single namespace.</p>
<p>In client projects at <a href="http://thinkrelevance.com/">Relevance</a> (home of <a href="http://clojure.com/">Clojure/core</a>) we often end up with one namespace for each aspect of an application — data access, UI, logging, and so on. Then there&#8217;s one &#8220;main&#8221; namespace that depends on all the others and ties it all together.</p>
<p><strong>Update 9/5/2011:</strong> Chris Houser wrote a nice answer on StackOverflow about <a href="http://stackoverflow.com/questions/4690758/splitting-a-clojure-namespace-over-multiple-files">how to split a Clojure namespace over several files</a>.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/iwwS36YzFcU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/08/08/clojure-namespaces/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/08/08/clojure-namespaces</feedburner:origLink></item>
		<item>
		<title>ClojureScript Launch, New York</title>
		<link>http://feedproxy.google.com/~r/StuartSierra/~3/MxvdCIB58Ok/clojurescript-launch-new-york</link>
		<comments>http://stuartsierra.com/2011/07/21/clojurescript-launch-new-york#comments</comments>
		<pubDate>Thu, 21 Jul 2011 21:04:31 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[ClojureScript]]></category>

		<guid isPermaLink="false">http://stuartsierra.com/?p=543</guid>
		<description><![CDATA[As you may have heard, last night we (Clojure/core) announced ClojureScript at the Clojure NYC Meetup. Rich Hickey gave a talk, which was streamed live over the web, while we monitored Twitter and IRC for feedback. The event was a &#8230; <a href="http://stuartsierra.com/2011/07/21/clojurescript-launch-new-york">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As you may have heard, last night we (<a title="Clojure/core: Clojure consulting services, support, and agile software development" href="http://clojure.com/">Clojure/core</a>) announced <a href="https://github.com/clojure/clojurescript">ClojureScript</a> at the <a href="http://www.meetup.com/Clojure-NYC/">Clojure NYC Meetup</a>. Rich Hickey gave a talk, which was streamed live over the web, while we monitored Twitter and IRC for feedback.</p>
<p>The event was a great success, with loads of excitement expressed by both the local New York crowd and the Internet at large.</p>
<div id="attachment_544" class="wp-caption alignnone" style="width: 310px"><a href="http://stuartsierra.com/wp-content/uploads/2011/07/2011-07-20-screenshot-during-clojurescript-talk.png"><img class="size-medium wp-image-544" title="2011-07-20-screenshot-during-clojurescript-talk" src="http://stuartsierra.com/wp-content/uploads/2011/07/2011-07-20-screenshot-during-clojurescript-talk-300x187.png" alt="Screenshot of IRC / Twitter during the ClojureScript announcement" width="300" height="187" /></a><p class="wp-caption-text">Screenshot of IRC / Twitter during the ClojureScript announcement</p></div>
<p>Video was also recorded, which will be posted soon.</p>
<p>Thanks to <a href="http://www.google.com/intl/ln/jobs/uslocations/new-york/index.html">Google New York</a> for hosting.</p>
<img src="http://feeds.feedburner.com/~r/StuartSierra/~4/MxvdCIB58Ok" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://stuartsierra.com/2011/07/21/clojurescript-launch-new-york/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://stuartsierra.com/2011/07/21/clojurescript-launch-new-york</feedburner:origLink></item>
	</channel>
</rss>

