<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>My work is the finger work</title>
 <link href="http://samskivert.com/blog/index.xml" rel="self"/>
 <link href="http://samskivert.com/blog/"/>
 <updated>2012-02-20T21:10:57-08:00</updated>
 <id>http://samskivert.com/blog/</id>
 <author>
   <name>Michael Bayne</name>
   <email>mdb@samskivert.com</email>
 </author>

 
 <entry>
   <title>Stars (and brackets) on thars</title>
   <link href="http://samskivert.com/blog/2012/02/stars-and-brackets-on-thars/"/>
   <updated>2012-02-09T00:00:00-08:00</updated>
   <id>http://samskivert.com/blog/2012/02/stars-and-brackets-on-thars</id>
   <content type="html">&lt;p&gt;One of my colleagues recently committed a change with the comment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Log Message:
-----------
Switching from &amp;quot;type *varname&amp;quot; to &amp;quot;type* varname&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It gave me hope for the future, that we might overcome the legacy of K&amp;amp;R&amp;#8217;s terrible mistake when they pioneered the styles &lt;code&gt;foo *pointer&lt;/code&gt; and &lt;code&gt;foo
array[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The world has mostly come around to the view that &lt;code&gt;[]&lt;/code&gt; is part of the type, not the variable (i.e. &lt;code&gt;foo[]&lt;/code&gt; is how you declare &amp;#8216;array of foo&amp;#8217;). In spite of this enlightenment, people cling to the syntax &lt;code&gt;foo *pointer&lt;/code&gt; even though obviously &lt;code&gt;foo*&lt;/code&gt; is how you declare &amp;#8216;pointer to foo&amp;#8217;.&lt;/p&gt;

&lt;p&gt;The reasoning is that you can declare:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='n'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;pointerToFoo&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;stackAllocatedFoo&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which is plainly confusing and a bad idea.&lt;/p&gt;

&lt;p&gt;Gosling was originally under the spell of K&amp;amp;R, but eventually came to his senses. Unfortunately, in Java the legacy of that madness lives on:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Test&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;one&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{},&lt;/span&gt; &lt;span class='n'&gt;two&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{},&lt;/span&gt; &lt;span class='n'&gt;three&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{};&lt;/span&gt;
        &lt;span class='c1'&gt;// one and two are of type String[], three is of type String[][]&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Naturally, C clings firmly to the past. The following is perfectly legal, if not the most maintainable, C:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='cp'&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;argc&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;char&lt;/span&gt;&lt;span class='o'&gt;**&lt;/span&gt; &lt;span class='n'&gt;argv&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kt'&gt;char&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;bar&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;printf&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;%ld %ld&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;sizeof&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='k'&gt;sizeof&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='c1'&gt;// prints 8 1 (or 4 1 if you&amp;#39;re on ye olde 32-bit machine)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The perspective of the enlightened language designer is that special-purpose type modifiers like &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;[]&lt;/code&gt; are a bad idea.&lt;/p&gt;

&lt;p&gt;Arrays can be handled simply. They should be a parameterized type. Scala and Haskell (and probably other Haskell-influenced languages) get this right:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='n'&gt;val&lt;/span&gt; &lt;span class='n'&gt;one&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='n'&gt;Array&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;No need for special syntax. In Scala&amp;#8217;s case they&amp;#8217;ve disallowed the declaration of multiple variables in the same clause, except for this weird construct which is a concession made to support Scala&amp;#8217;s highly unfortunate &lt;code&gt;enum&lt;/code&gt; pattern:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='n'&gt;val&lt;/span&gt; &lt;span class='n'&gt;onePlusOne&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;twoTimesOne&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;fourDivTwo&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='n'&gt;Int&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='c1'&gt;// all vals bound to 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Pointers are trickier business. For one, a civilized language doesn&amp;#8217;t have pointers, which cuts the conversion pretty short. However, civilized languages do have have reference types, which are basically the same thing without the promise of naughtiness and adventure.&lt;/p&gt;

&lt;p&gt;One can mostly get by with glossing over the difference between reference types and value types. When you write:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;bar&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mh'&gt;0xf00&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;it&amp;#8217;s not a great mystery that &lt;code&gt;foo&lt;/code&gt; is a pointer to a string and &lt;code&gt;bar&lt;/code&gt; is just an int on the stack. However, if you allow the creation of value types that are larger than the machine&amp;#8217;s register size (e.g. &lt;code&gt;Vector3&lt;/code&gt;, &lt;code&gt;Matrix4&lt;/code&gt;, etc.), you will invariably want to pass them by reference.&lt;/p&gt;

&lt;p&gt;Java cleverly avoids this conundrum by restricting itself to only built-in value types which fit into registers. That&amp;#8217;s the sort of approach that&amp;#8217;s likely to get you &lt;a href='http://en.wikipedia.org/wiki/Triviality_(mathematics)'&gt;zero credit on your math homework&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;C# takes a crack at a non-zero solution with &lt;code&gt;ref&lt;/code&gt; parameters. You can declare:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c#'&gt;&lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;invert&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;ref&lt;/span&gt; &lt;span class='n'&gt;Matrix4&lt;/span&gt; &lt;span class='n'&gt;matrix&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;...&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and your calls to &lt;code&gt;invert&lt;/code&gt; will not involve copying 16 doubles. We can deduce Hejlsberg&amp;#8217;s enlightened status by the fact that it&amp;#8217;s &lt;code&gt;ref Matrix4&lt;/code&gt; and not &lt;code&gt;Matrix4 ref&lt;/code&gt; (the latter being the moral equivalent of &lt;code&gt;Matrix4*&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;However, I expect that if the JVM some day supports value types, Odersky&amp;#8217;s modeling of them in Scala will be something even more enlightened, like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='n'&gt;void&lt;/span&gt; &lt;span class='n'&gt;invert&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;matrix&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Ref&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Matrix4&lt;/span&gt;&lt;span class='o'&gt;])&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Such an approach nicely mirrors &lt;code&gt;Array[Matrix4]&lt;/code&gt; and avoids the need to introduce a new keyword into the language. Scala already supports implicit conversions, so a conversion from &lt;code&gt;A&lt;/code&gt; to &lt;code&gt;Ref[A]&lt;/code&gt; is as simple as:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='n'&gt;implict&lt;/span&gt; &lt;span class='n'&gt;toRef&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;A&lt;/span&gt; &lt;span class='k'&gt;&amp;lt;:&lt;/span&gt; &lt;span class='kt'&gt;AnyVal&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;value&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;A&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Ref&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;A&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt; &lt;span class='c1'&gt;// implemented by compiler magic!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Under the hood, the compiler would emit the appropriate byte codes to indicate by-reference-ness, but there&amp;#8217;s no need to sully the language with evidence of those machinations when there are already perfectly good abstractions available to model them.&lt;/p&gt;

&lt;p&gt;C# also supports &lt;code&gt;out&lt;/code&gt; parameters, allowing one to write:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c#'&gt;&lt;span class='kt'&gt;bool&lt;/span&gt; &lt;span class='nf'&gt;getId&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;out&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;...&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;getId&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// I have an id!&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;id&lt;/code&gt; is considered uninitialized in the body of &lt;code&gt;getId&lt;/code&gt; and must be initialized before &lt;code&gt;getId&lt;/code&gt; returns (modulo exceptions).&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not sure such a thing could be modeled with a standard OOP type system, so perhaps this is a good case for special syntax. However, this whole mechanism exists solely to support multiple return values. The combination of a &lt;code&gt;Tuple&lt;/code&gt; value type, deconstructing binding, and under-the-hood optimizations solve this problem without special cases. The following is already legal Scala code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;getId&lt;/span&gt;&lt;span class='o'&gt;()&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='kt'&gt;Boolean&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt;

&lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;gotId&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;getId&lt;/span&gt;&lt;span class='o'&gt;()&lt;/span&gt;
&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;gotId&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// I have an id!&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Just add value types to the JVM and said under-the-hood optimizations, and you&amp;#8217;re good to go.&lt;/p&gt;

&lt;p&gt;Anyhow, I seem to have rambled pretty far afield. I&amp;#8217;ll stop philosophizing and go back to being happy that the world contains a few fewer &lt;code&gt;type *foo&lt;/code&gt; declarations. Some day we may live in a world where there are no &lt;code&gt;*&lt;/code&gt;s upon ours.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Happy New Year to Me!</title>
   <link href="http://samskivert.com/blog/2012/01/happy-new-year-to-me/"/>
   <updated>2012-01-03T00:00:00-08:00</updated>
   <id>http://samskivert.com/blog/2012/01/happy-new-year-to-me</id>
   <content type="html">&lt;p&gt;I logged into the server that hosts samskivert.com yesterday and noticed that someone had done a very ham fisted job of hacking into my server (in addition to whatever nefarious business they hacked in to perpetrate, they changed the uid of my primary account to 0 and left the passwd file thusly modified). That&amp;#8217;s what I get for having anything other than Apache and sshd running.&lt;/p&gt;

&lt;p&gt;Naturally, the only thing to do in such a case was to take off and nuke the site from orbit. So I slurped down all the data from my &lt;a href='http://www.slicehost.com/'&gt;slice&lt;/a&gt; and pressed the big red button that wiped the slice and reinstalled a fresh Ubuntu image (upgrading everything in the process, how nice).&lt;/p&gt;

&lt;p&gt;Then I copied all the data back up to the machine and started setting things back up. That&amp;#8217;s when I realized that I forgot to grab the MySQL databases. Oops! No problem, I have scripts that back everything up to S3. I fired up the S3 console and discovered that the directory that should contain the database backups was empty. Double oops! I guess something broke at some point in the five years since I set all that up.&lt;/p&gt;

&lt;p&gt;The only thing that used MySQL was my WordPress install. There went thirteen years of blogging. I was ready to declare the world a better place for lack of my inane writing, but then I realized that Google Reader probably had most of my blog archived. Not only that, but it made it pretty easy to slurp down said archives.&lt;/p&gt;

&lt;p&gt;One of the things I do to simplify my life, now that I&amp;#8217;m old and forgetful, is to give up on trying to re-memorize things that I&amp;#8217;ve forgotten, and instead to change the world to match what little I can remember. For example, if I forget the password to some account and have to reset it, I change it to the first thing I guessed might be my password when I was trying to log in. In this case, since I forgot that I had MySQL databases that needed copying, I should probably avoid creating new databases that I will undoubtedly forget about the next time this sort of thing happens.&lt;/p&gt;

&lt;p&gt;Instead of setting WordPress back up, I set up &lt;a href='https://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt;: a bunch of Ruby scripts that generate a blog based on flat files. The flat files can be committed to a Git repository. I definitely did not forget to copy my Git repositories. Indeed, I went one better and just moved &lt;a href='https://github.com/samskivert/website'&gt;my website Git repository&lt;/a&gt; to Github so that I can not worry about backing it up in the first place.&lt;/p&gt;

&lt;p&gt;A few Perl and Scala scripts later and I had converted the Google Reader blog archives into a format acceptable to Jekyll. It turns out the Google Reader archives only went back to 2005 or so. Having come this far, I didn&amp;#8217;t feel like settling for recovering only half of my blog, so I slurped down the Google caches for my web site and extracted the posts from 1999 through 2005.&lt;/p&gt;

&lt;p&gt;I took the opportunity to factor my reviews from my blog-proper (even though both contain half-baked opinions). I set up redirects that &lt;em&gt;should&lt;/em&gt; allow RSS readers to seamlessly continue to operate with the new setup, though this post will put the test to that hypothesis.&lt;/p&gt;

&lt;p&gt;Another nice thing about switching away from WordPress is that I no longer need to maintain fiddly WordPress caching plugins (and associated Apache .htaccess machinery), nor do I need to run a Varnish reverse proxy to ensure that things stay performant if I ever post something that the world wants to read. Simple simple simple!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>“Fun with edge cases” or “Why your spec can never possibly be complete”</title>
   <link href="http://samskivert.com/blog/2011/08/fun-with-edge-cases-or-why-your-spec-can-never-possibly-be-complete/"/>
   <updated>2011-08-12T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2011/08/fun-with-edge-cases-or-why-your-spec-can-never-possibly-be-complete</id>
   <content type="html">&lt;p&gt;(Apologies for the duplication with Google+, still sorting out my syndication process.)&lt;/p&gt;

&lt;p&gt;What do you think should happen if you do the following in Java?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='n'&gt;Map&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;HashMap&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;();&lt;/span&gt;
&lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;put&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;span class='n'&gt;Iterator&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;Map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;Entry&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;iter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;entrySet&lt;/span&gt;&lt;span class='o'&gt;().&lt;/span&gt;&lt;span class='na'&gt;iterator&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
&lt;span class='n'&gt;Map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;Entry&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;entry&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;iter&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;next&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
&lt;span class='n'&gt;iter&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;remove&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
&lt;span class='n'&gt;entry&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;setValue&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Should the entry freak out because you tried to update the mapping after it has already been removed? Should it reintroduce a mapping from “foo” to “baz”? Should the call succeed but have no effect on the map?&lt;/p&gt;

&lt;p&gt;Java actually specifies the behavior as undefined. So perhaps your spec can be complete by pushing the burden onto the developer of ensuring that they never rely on any undefined behavior. The HashMap implementation’s interpretation of “undefined” is “allow the call to succeed and don’t modify the underlying map.” That makes it more difficult to ensure you’re not relying on undefined behavior than if it, say, threw an exception.&lt;/p&gt;

&lt;p&gt;Perhaps the question on your mind is “Gee Mike, how do you find yourself in the position of caring about something like this?” The answer to that lies in &lt;a href='https://github.com/threerings/react/blob/master/src/main/java/react/RMap.java'&gt;this code&lt;/a&gt;, which chooses a different interpretation of undefined.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Forecast: cloudy</title>
   <link href="http://samskivert.com/blog/2011/06/forecast-cloudy/"/>
   <updated>2011-06-04T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2011/06/forecast-cloudy</id>
   <content type="html">&lt;p&gt;Far too often, Google App Engine reports that everything is smooth sailing:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/2011/06/alls-well-gae.png&quot; height=&quot;669&quot; alt=&quot;&quot; title=&quot;Full speed ahead Cap&amp;#39;n!&quot;&gt;&lt;/p&gt;
&lt;p&gt;when the view from my app looks substantially less rosy:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/2011/06/or-not-gae.png&quot; alt=&quot;&quot; title=&quot;Oh, what&amp;#39;s that iceberg?&quot; width=&quot;776&quot; height=&quot;auto&quot;&gt;&lt;/p&gt;
&lt;p&gt;My app is not complex. It stuffs data into the app engine data store and pulls it back out again. The total size of all my entities is &lt;a href=&quot;http://www.youtube.com/watch?v=-DJtHL3NV1o&quot;&gt;one meeeellion bytes&lt;/a&gt;. The code is not massive; it’s seven jar files, the largest of which is the app engine API. It has less than five regular users. Aside from the fact that GAE’s design necessitates that about 80% of the requests involve starting up a JVM and initializing the whole webapp, it really ought not to be taxing their gigascale infrastructure.&lt;/p&gt;
&lt;p&gt;After being unable to use it for 48 hours — again — this broke-back camel is going to limp off and rewrite the backend in SQL and move the damned thing to my Slicehost server. Hopefully GAE will be working again soon so that I can download my data.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Too much Maven Kool-aid</title>
   <link href="http://samskivert.com/blog/2011/06/too-much-maven-kool-aid/"/>
   <updated>2011-06-02T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2011/06/too-much-maven-kool-aid</id>
   <content type="html">&lt;p&gt;A &lt;a href=&quot;http://www.sonatype.com/people/2008/05/adding-additional-source-folders-to-your-maven-build/&quot;&gt;post on the Sonatype blog&lt;/a&gt; cheerfully reports:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Adding an additional source folder is as simple as:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;project&amp;gt;
  ...
  &amp;lt;build&amp;gt;
    &amp;lt;plugins&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;
        &amp;lt;executions&amp;gt;
          &amp;lt;execution&amp;gt;
            &amp;lt;id&amp;gt;add-source&amp;lt;/id&amp;gt;
            &amp;lt;phase&amp;gt;generate-sources&amp;lt;/phase&amp;gt;
            &amp;lt;goals&amp;gt;
              &amp;lt;goal&amp;gt;add-source&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
            &amp;lt;configuration&amp;gt;
              &amp;lt;sources&amp;gt;
                &amp;lt;source&amp;gt;some directory&amp;lt;/source&amp;gt;
                ...
              &amp;lt;/sources&amp;gt;
            &amp;lt;/configuration&amp;gt;
          &amp;lt;/execution&amp;gt;
        &amp;lt;/executions&amp;gt;
      &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
  &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;If that’s simple, I don’t want to see complicated.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How I Learned to Stop Worrying and Love (Coding on) the Mac OS</title>
   <link href="http://samskivert.com/blog/2011/05/how-i-learned-to-stop-worrying-and-love-coding-on-the-mac-os/"/>
   <updated>2011-05-24T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2011/05/how-i-learned-to-stop-worrying-and-love-coding-on-the-mac-os</id>
   <content type="html">&lt;p&gt;I’ve been using Linux and X Windows as my primary operating system for development for a long time. Owing to the spotty or non-existent support of consumer applications over the years, I have generally maintained an auxiliary machine (sometimes Windows, sometimes a Mac) on which to run things like iTunes or the Flash Authoring Tool (or even the Flash player when Linux support was crap).&lt;/p&gt;
&lt;p&gt;My primary machine has generally been a Mac, because I like the hardware, I just haven’t ever run Mac OS on it. Or rather, I would periodically attempt to switch to the Mac OS for development and then switch back to Linux after a week or so, annoyed at the hundred tiny ways in which my efficiency was reduced.&lt;/p&gt;
&lt;p&gt;A few months ago, I resolved to overcome the remaining obstacles by whatever means necessary (even if it meant writing Application Enhancer modules, though it didn’t come to that). I’ve now been happily coding away on Mac OS for multiple months, so I think it’s time to declare victory and record for posterity the various hacks and configuration tweaks that make my life tolerable.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Virtual Desktops&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The Mac has long lacked civilized virtual desktop support. Frankly, it still sucks, but between some hackery and some finger retraining, I’ve managed to cobble together behavior that I can live with. In the Linux world, I had what I consider to be the ideal behavior:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instant switching between desktops. I don’t need to waste hundreds of milliseconds waiting for some animated transition to complete.&lt;/li&gt;
&lt;li&gt;Direct switching to a desktop via Alt-Fn. Don’t make me use arrow keys to navigate my desktops (or heaven forbid, the mouse). I know where I want to go, and I want to get there with a single key combination. I also don’t want that key combination to be Alt-n because certain web browsers (i.e. Firefox and Chrome) use those keys to instantly switch between tabs, which I also use heavily.&lt;/li&gt;
&lt;li&gt;When on a particular desktop, Alt-Tab switches between &lt;em&gt;only&lt;/em&gt; the windows on that desktop. As far as I’m concerned, the other desktops don’t exist unless I switch to them. Each desktop is its own tiny universe.&lt;/li&gt;
&lt;li&gt;When switching to a desktop, the window that had focus when I left that desktop has focus when I return.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was not able to recreate this desktop utopia fully, but here’s what I did. First, disable desktop animation transitions thusly:&lt;/p&gt;
&lt;pre&gt;
defaults write com.apple.dock workspaces-swoosh-animation-off -bool YES &amp;amp;&amp;amp; killall Dock
&lt;/pre&gt;
&lt;p&gt;Next, install &lt;a href=&quot;http://thecocoabots.com/hyperspaces/&quot;&gt;Hyperspaces&lt;/a&gt; which allows you to map arbitrary key shortcuts for switching between spaces. You may also need to disable the default Spaces key shortcuts. Note also: the use of Hyperspaces works around an &lt;a href=&quot;https://discussions.apple.com/thread/2161076?threadID=2161076&quot;&gt;infuriating Spaces bug&lt;/a&gt;, which I repeatedly encountered when I was trying the “just give up on the utility of Alt-n in Firefox/Chrome” approach.&lt;/p&gt;
&lt;p&gt;I still have to live with the fact that Alt-Tab and Spaces interact in absurd ways, and that Alt-Tab in general switches between &lt;em&gt;applications&lt;/em&gt;, not &lt;em&gt;windows&lt;/em&gt;. I have to switch between Alt-Tab and Alt-` if I want to get to a particular Terminal window. Spaces also does suboptimal things with focus when returning to a Space. It attempts to preserve focus in the same application if it can. If I have Terminal focused on one Space and switch to another Space with a Terminal window on it, that Terminal window will get focus regardless of what window last had focus on that Space. Only if no window from the same application is open on the target Space will it give focus to the last window that had it. Useful!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ctrl-Meta-Cokebottle&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I’m an emacs user, and thus I have many neurons in my peripheral nervous system dedicated to the use of the Control and Meta keys. (Meta is called Alt on PC10x keyboards and Command on Mac keyboards.) The way my fingers wish to use these keys causes numerous problems on the Mac OS.&lt;/p&gt;
&lt;p&gt;I can’t use the sexy slim Mac keyboards, because I have to remap Caps-Lock to Ctrl (naturally), and the Caps-Lock key sucks. Five times out of ten, instead of registering ‘Ctrl-a’, the keyboard registers ‘a’ and happily inserts it into my buffer (same goes for ‘Ctrl-e’ and ‘e’, etc.). Since I use Ctrl-a/e about fifteen times a minute, this is somewhat problematic. Thus, in front of my sexy Apple Cinema display, above my sculpted aluminum Mac Pro, I have a very non-slim, boxy, black KeyTronic KT800U.&lt;/p&gt;
&lt;p&gt;In addition to remapping Caps-Lock to Ctrl, I have to swap Command (Alt) and Option (funny-Windows-symbol); for some reason Apple chose to wire those two keys backwards on their keyboards. This is easily accomplished in the Modifier Keys popup of the Keyboard preferences, but it does not solve the larger problem that the Mac uses the Command key for all of its application shortcuts. In certain applications where I expect my emacs key bindings to work, like Terminal, it gets pretty annoying that, for example, Command-d splits the Terminal window into two panes, rather than deleting to the next word boundary. It’s not 15 times a minute annoying, but it’s still pretty bad.&lt;/p&gt;
&lt;p&gt;This Terminal Command key issue had long been the primary insurmountable obstacle that sent me back to Linux. In Emacs.app, they thankfully make the Command key do the right thing, but I spend enough time in Terminal to eventually be driven crazy. Enter &lt;a href=&quot;https://github.com/aim-stuff/cmd-key-happy&quot;&gt;cmd-key-happy&lt;/a&gt;, my savior. This handy utility allows one to reclaim the Command key in any application, while leaving any specific Command key shortcuts in place (like Command-x/c/v and Command-Tab). It’s very useful if you want to use emacs key bindings in Eclipse or XCode as well.&lt;/p&gt;
&lt;p&gt;I also went into the Keyboard → Keyboard Shortcuts preferences pane and disabled a bunch of global key shortcuts that caused my emacs-trained fingers to betray me in various circumstances. Specifically: Dashboard &amp;amp; Dock → Turn Dock Hiding On/Off, Front Row → Hide and show Front Row, Service → Make New Sticky Note, Application Shortcuts → Show Help menu.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;I can has Terminal&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I used &lt;a href=&quot;http://packages.debian.org/sid/keylaunch&quot;&gt;keylaunch&lt;/a&gt; on Linux to provide global key shortcuts for opening a new xterm and a few other incidentals. Most of that I have learned to live without, but opening a new Terminal window to do some quick shell noodling is something I do all the damned time. Through a combination of Automator.app and some AppleScript, I managed to recreate this functionality without having to install yet another piece-of-crap shareware utility.&lt;/p&gt;
&lt;p&gt;In Automator, I created a new Service automation, with the following Run AppleScript action:&lt;/p&gt;
&lt;pre&gt;
on run {input, parameters}
	tell application &amp;quot;Terminal&amp;quot;
		do script &amp;quot;&amp;quot;
		activate
	end tell
	return input
end run
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;do script &quot;&quot;&lt;/code&gt; instructs Terminal to execute the empty command, and it opens a new Terminal in the current Space in which to do so. &lt;code&gt;activate&lt;/code&gt; tells it to give said window focus. Since AppleScript has approximately fuckall understanding of Spaces, the fact that this works at all was a lucky happenstance.&lt;/p&gt;
&lt;p&gt;This automation I then saved (cleverly named “New Terminal”). In the Keyboard → Keyboard Shortcuts preferences, under Application Shortcuts, I created a new shortcut (named “New Terminal”, which is how it knows which automation to use), and configured my desired key combination (Command-Esc). Said shortcut magically appears in the Services menu of every application, and the key combination usually even works when I press it (like many aspects of Mac OS, sometimes it mysteriously fails).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;An Emacs on Every Desktop&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Prior to setting up &lt;a href=&quot;http://samskivert.com/2010/08/an-emacs-on-every-desktop/&quot;&gt;scripts to run one emacs instance on each virtual desktop&lt;/a&gt;, I coped with the default behavior, which was to open a new instance of emacs every time I ran &lt;code&gt;emacs somefile&lt;/code&gt; from the command line. This wasn’t so bad, since I usually just open files from within my existing emacs instance, and it at least allowed me to have one (or sometimes more than one) emacs on each virtual desktop.&lt;/p&gt;
&lt;p&gt;However, the default behavior on the Mac is for there to be one instance of Emacs.app running ever, and for all new files to open in that instance. This interacts very poorly with my normal workflow of having different virtual desktops devoted to different programming projects. For a while, I tried opening multiple frames (via &lt;code&gt;M-x new-frame&lt;/code&gt;), and having one frame on each Space. Emacs.app was usually smart enough to respond to &lt;code&gt;open -a Emacs.app somefile&lt;/code&gt; by opening the file in the frame on the current Space. The major downside was that all my buffers across all projects were all mixed together in a single emacs instance, which sucked in various ways.&lt;/p&gt;
&lt;p&gt;After a great deal of digging, I discovered &lt;a href=&quot;http://hints.macworld.com/article.php?story=20080227075244778&quot;&gt;a terrible hack&lt;/a&gt; for determining the number of the current Space via AppleScript. I put that into a script that I could use with my &lt;a href=&quot;http://samskivert.com/2010/08/an-emacs-on-every-desktop/&quot;&gt;previous setup&lt;/a&gt; to achieve a separate emacs instance on each Space.&lt;/p&gt;
&lt;pre&gt;
#!/usr/bin/osascript

set xxVar to 0
tell application &amp;quot;System Events&amp;quot;
tell process &amp;quot;SystemUIServer&amp;quot;
set xVar to value of attribute &amp;quot;AXChildren&amp;quot; of menu bar 1
set cVar to count of xVar
repeat with iVar from 1 to cVar
    set zVar to value of attribute &amp;quot;AXDescription&amp;quot; of item iVar of xVar
    try
        if zVar = &amp;quot;spaces menu extra&amp;quot; then
            set xxVar to iVar
            exit repeat
        end if
    end try
end repeat
end tell
end tell

if xxVar = 0 then
    display dialog &amp;quot;Spaces Menu Extra not installed&amp;quot;
else
    tell application &amp;quot;System Events&amp;quot;
    tell process &amp;quot;SystemUIServer&amp;quot;
    set theCurrentSpace to value of menu bar item xxVar of menu bar 1
    end tell
    end tell

    -- Do what you want with &amp;quot;theCurrentSpace&amp;quot; variable starting here
    get theCurrentSpace as number
    -- Do what you want with &amp;quot;theCurrentSpace&amp;quot; variable ending here
end if
&lt;/pre&gt;
&lt;p&gt;This script requires that the Spaces menu be visible, which duplicates the Hyperspaces menu (which cannot be disabled). I also end up with three or four Emacs.app icons in the dock and in the Alt-Tab menu (with no way to tell which is on which space, since they are reordered based on when they were last used). However, these are small prices to pay for the joy of segregated buffers.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Fine Beverages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Naturally, there are a few dozen Unix utilities that I needed in order to pursue my nefarious goals. In the past, I had used &lt;a href=&quot;http://www.finkproject.org/&quot;&gt;Fink&lt;/a&gt; or &lt;a href=&quot;http://www.macports.org/&quot;&gt;MacPorts&lt;/a&gt;, but now I’m a fan of &lt;a href=&quot;https://github.com/mxcl/homebrew&quot;&gt;Homebrew&lt;/a&gt;. I like not installing packages as root, and having them each installed into their own little directory tree and symlinked into the giant mishmash of /usr/local.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Your Suggestions Here&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;That’s the extent of the wrangling I’ve done to make the Mac OS a moderately pleasant place to develop. Well, that and to install an SSD because the filesystem or caching subsystem or something was causing builds to take 20-30% longer. If you, dear reader, have further suggestions for a reformed Linux user, please post them in the comments.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler 66</title>
   <link href="http://samskivert.com/blog/2011/01/euler-66/"/>
   <updated>2011-01-14T00:00:00-08:00</updated>
   <id>http://samskivert.com/blog/2011/01/euler-66</id>
   <content type="html">&lt;p&gt;&lt;a href='http://projecteuler.net/index.php?section=problems&amp;amp;id=66'&gt;Problem 066&lt;/a&gt;: (&lt;a href='http://github.com/samskivert/euler-scala/raw/master/Euler066.scala'&gt;source&lt;/a&gt;):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='k'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;scala.collection.mutable.&lt;/span&gt;&lt;span class='o'&gt;{&lt;/span&gt;&lt;span class='nc'&gt;Map&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;object&lt;/span&gt; &lt;span class='nc'&gt;Euler066&lt;/span&gt; &lt;span class='k'&gt;extends&lt;/span&gt; &lt;span class='nc'&gt;EulerApp&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;leastx&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;amap&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;,&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;]()&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;pmap&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;,&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;]()&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;qmap&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;,&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;]()&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;ppmap&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;,&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;]()&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;qqmap&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;MMap&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;,&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;]()&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;amap&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;getOrElseUpdate&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sqrt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;toInt&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;_&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;pp&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;))/&lt;/span&gt;&lt;span class='n'&gt;qq&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;})&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;pmap&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;getOrElseUpdate&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;_&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;})&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;q&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;qmap&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;getOrElseUpdate&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;_&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;q&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;q&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;})&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;pp&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ppmap&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;getOrElseUpdate&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;_&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;qq&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;pp&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;})&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;qq&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;qqmap&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;getOrElseUpdate&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;_&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='nc'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;pp&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;)*&lt;/span&gt;&lt;span class='n'&gt;pp&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;))/&lt;/span&gt;&lt;span class='n'&gt;qq&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;})&lt;/span&gt;

    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;as&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Stream&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;from&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;as&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tail&lt;/span&gt; &lt;span class='n'&gt;takeWhile&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ai&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;ai&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='n'&gt;as&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;head&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;length&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
  &lt;span class='o'&gt;}&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;square&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;issquare&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;square&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sqrt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;toInt&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;answer&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='n'&gt;to&lt;/span&gt; &lt;span class='mi'&gt;1000&lt;/span&gt; &lt;span class='n'&gt;filterNot&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;issquare&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;leastx&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;)))&lt;/span&gt; &lt;span class='n'&gt;sortBy&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;_&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;_2&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;last&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;_1&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;My efforts to post my Euler solutions with commentary remain woefully behind (I just finished problem 110), but when I took action to close this gap, I discovered that I had skipped over problem 66 so long ago. I recall being frustrated after beating my head against it for a while and making no headway.&lt;/p&gt;

&lt;p&gt;Filled with renewed vigor, I tackled it again here under the invigorating Mexican sunshine. Alas, the sunshine proved to be of little help. I spent a long time wrangling with the equation in the form &lt;em&gt;y² = (x+1)(x-1)/D&lt;/em&gt;. This led me to explore the family of solutions &lt;em&gt;nD + 1&lt;/em&gt; and &lt;em&gt;nD – 1&lt;/em&gt;, which are very nice, but definitely not minimal.&lt;/p&gt;

&lt;p&gt;I then played around with factoring &lt;em&gt;D&lt;/em&gt; and trying to come up with some way to efficiently search for potential solutions using those factors, since &lt;em&gt;D&lt;/em&gt; has to divide evenly into &lt;em&gt;(x + 1)(x – 1)&lt;/em&gt;. But it needn&amp;#8217;t do so in any convenient way. For example, for &lt;em&gt;D = 28&lt;/em&gt;, the minimal solution is &lt;em&gt;(127 + 1)(127 – 1)/28&lt;/em&gt; which factors into &lt;em&gt;2 · 2 · 2 · 2 · 2 · 2 · 2 × 2 · 3 · 3 · 7 / 7 · 2 · 2&lt;/em&gt;. Some of the factors go into the left numerator and some in the right, it&amp;#8217;s mayhem.&lt;/p&gt;

&lt;p&gt;Eventually I decided to do some Googling and discovered that this is closely related to the well-known &lt;a href='http://mathworld.wolfram.com/PellEquation.html'&gt;Pell equation&lt;/a&gt;. For reasons not entirely clear to me, its solutions lie in the continued fraction expansion of the square root of &lt;em&gt;D&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Implementing the “usual recurrence relations&amp;#8221; was pretty straightforward, though a bit of memoization was needed (the unsightliness of that part of the code annoys me, but I am annoyed enough with this problem already that I don&amp;#8217;t feel like twiddling it further). &lt;code&gt;BigInt&lt;/code&gt; also turned out to be necessary, as the largest “minimal&amp;#8221; &lt;em&gt;x&lt;/em&gt; is &lt;em&gt;16421658242965910275055840472270471049&lt;/em&gt;, which doesn&amp;#8217;t quite fit into 64 bits.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Euler 65</title>
   <link href="http://samskivert.com/blog/2011/01/euler-65/"/>
   <updated>2011-01-13T00:00:00-08:00</updated>
   <id>http://samskivert.com/blog/2011/01/euler-65</id>
   <content type="html">&lt;p&gt;&lt;a href='http://projecteuler.net/index.php?section=problems&amp;amp;id=65'&gt;Problem 065&lt;/a&gt;: (&lt;a href='http://github.com/samskivert/euler-scala/raw/master/Euler065.scala'&gt;source&lt;/a&gt;):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='k'&gt;object&lt;/span&gt; &lt;span class='nc'&gt;Euler065&lt;/span&gt; &lt;span class='k'&gt;extends&lt;/span&gt; &lt;span class='nc'&gt;EulerApp&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Frac&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;numer&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;denom&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Frac&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;denom&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;numer&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;denom&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;invert&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Frac&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;denom&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;numer&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
  &lt;span class='o'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;compute&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Frac&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;term&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;*(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='nc'&gt;Frac&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;term&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='n'&gt;compute&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;invert&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;term&lt;/span&gt;
  &lt;span class='o'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;answer&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;compute&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;numer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;toString&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;_-&lt;/span&gt;&lt;span class='sc'&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;sum&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The only challenge here is algorithmizing the computation of the continued fraction, while preserving the numerator and denominator, so that we can compute the answer from the final numerator. I think the case class makes the calculations on the fraction much tidier.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The eternal quest for personal information management nirvanaz</title>
   <link href="http://samskivert.com/blog/2010/11/the-eternal-quest-for-personal-information-management-nirvana/"/>
   <updated>2010-11-28T00:00:00-08:00</updated>
   <id>http://samskivert.com/blog/2010/11/the-eternal-quest-for-personal-information-management-nirvana</id>
   <content type="html">&lt;p&gt;I have progressed through a broad variety of personal information management tools over the course of my life, and they invariably fail to meet my needs in one way or another. This periodically motivates a flurry of note taking on what would comprise the “perfect” personal information management system, which I generally record using whatever duct tape and baling wire contraption I am currently using to keep track of things, and then promptly forget about.&lt;/p&gt;
&lt;p&gt;About half a decade ago, I wrote a &lt;a href=&quot;http://samskivert.com/code/jikan&quot;&gt;standalone application&lt;/a&gt; that handled the parts of PIM that were done &lt;em&gt;wrongly&lt;/em&gt;, in my opinion, by other tools (keeping lists of tasks to do, a journal of daily doings, and seeing at a glance what events were upcoming and recently past). It kept the urges to write a more comprehensive system at bay, and I got by with my tool, a haphazard collection of wikis and text files, and Google calendar.&lt;/p&gt;
&lt;p&gt;My entry into the world of computer science research last year triggered a dramatic increase in my generation of notes and ideas that needed keeping track of, not to mention a much more finely divided schedule. To meet my increased PIM needs, I tried &lt;a href=&quot;http://code.google.com/p/w2wiki/&quot;&gt;minimalist solutions&lt;/a&gt;, &lt;a href=&quot;http://twiki.org/&quot;&gt;maximalist solutions&lt;/a&gt;, and &lt;a href=&quot;https://sites.google.com/&quot;&gt;Googly solutions&lt;/a&gt; (among &lt;a href=&quot;http://culturedcode.com/things/&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;http://www.rememberthemilk.com/&quot;&gt;dozen&lt;/a&gt; &lt;a href=&quot;http://www.evernote.com/&quot;&gt;others&lt;/a&gt;&lt;a href=&quot;http://www.google.com/notebook/&quot;&gt;.&lt;/a&gt;&lt;a href=&quot;http://backpackit.com/&quot;&gt;.&lt;/a&gt;&lt;a href=&quot;http://projects.gnome.org/tomboy/&quot;&gt;.&lt;/a&gt;). Each rewarded my substantial organizational efforts with eventual dissatisfaction and malaise. My resolve eventually eroded and I succumbed to my perennial urge to write my own all-singing, all-dancing, wiki/todo/calendar/datastore/dwim application.&lt;/p&gt;
&lt;p&gt;I thus present &lt;a href=&quot;http://sparecortex.com&quot;&gt;Spare Cortex&lt;/a&gt;, an unabashed indulgence in my own personal information management needs. To atone for the sin of polluting the world with yet another wiki, I have strived to make it usable by people other than its author. I have provided a &lt;a href=&quot;http://sparecortex.com/c/demo&quot;&gt;demonstration of its basic functionality&lt;/a&gt; to help interested parties determine whether it is worth the time investment of trying out.&lt;/p&gt;
&lt;p&gt;My motivations in creating the system (which you may compare to your own PIM motivations to gauge your interest) were as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It should not extravagantly waste a quarter or more of its screen real estate on headers, banners, navigation links and other wikijunk (to paraphrase &lt;a href=&quot;http://en.wikipedia.org/wiki/Chartjunk&quot;&gt;Tufte&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;It should be hierarchical. The flat namespace of most wiki systems breaks down once you add half a dozen projects each with a dozen pages of content. Prefixing the name of every page with the name of its parents scales poorly. &lt;/li&gt;
&lt;li&gt;It should support structured content (most importantly checklists, and what I call “pages”) natively. Configuring half a dozen poorly implemented and unmaintained plugins is a punishment I’d rather avoid.&lt;/li&gt;
&lt;li&gt;With regard to checklists, having to open the wiki editor and scroll down through a sea of text to find a todo item to check off (or edit, or move up or down in priority) is painful.&lt;/li&gt;
&lt;li&gt;With regard to pages, any project that does not die an early death will eventually accumulate sort of “dashboard” at its top-level, containing outstanding todo items, lists of useful resources, and the top-level links to the copious notes that you’ve taken as the project evolves. Basic page layout capabilities enable one to organize this dashboard page in a way that allows easy viewing of what’s going on with the project and easy updating of ephemeral data.&lt;/li&gt;
&lt;li&gt;Furthermore, I don’t want that data landlocked amidst semi-structured text. I should be able to see all of the tasks across all of my projects, or tag individual tasks and place a view of tasks with e.g. the &lt;em&gt;today&lt;/em&gt; tag on my top-level “life dashboard” page, alongside my appointments and journal (note: the tagging feature is not yet complete, but is soon forthcoming).&lt;/li&gt;
&lt;li&gt;Parts of pages, like checklists, should be accessible at individual URLs which are mobile web browser friendly, so that you can readily access any task list while on the go, and quickly add whatever thought popped into your head.&lt;/li&gt;
&lt;li&gt;It should support the attachment of media to individual pages, again not constrained by a global namespace.&lt;/li&gt;
&lt;li&gt;It should be searchable (not yet implemented) and support bulk import and export (also not yet implemented).&lt;/li&gt;
&lt;li&gt;It should support access controls to enable sharing subtrees (or an entire tree) in a read-only or read-write manner with other people, or with the anonymous public (partly implemented).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The system is implemented on Google’s AppEngine, which I confess to having mixed feelings about. Its reliability has been less than stellar during the course of development, though it seems to be improving lately. Further rants on that subject should occupy their own blog post. Should you make use of Spare Cortex for your own information management needs, you can rest comfortably in the knowledge that I’m highly motivated to keep it running smoothly, owing to my own repeated daily use.&lt;/p&gt;
&lt;p&gt;If you’ve managed to read this far and are not simply in shock at this display of raw enthusiasm for something of such little consequence, please &lt;a href=&quot;http://www.sparecortex.com/&quot;&gt;give Spare Cortex a whirl&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>WTFF?</title>
   <link href="http://samskivert.com/blog/2010/09/wtff/"/>
   <updated>2010-09-14T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/wtff</id>
   <content type="html">&lt;p&gt;I saw some weird background activity on my network interface and undertook an investigation. &lt;code&gt;netstat&lt;/code&gt; readily revealed that Firefox had a metric ton of TCP connections open:&lt;/p&gt;
&lt;pre&gt;
yonami.local:58809      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:58828      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:33425      pv-in-f106.1e100.ne:www ESTABLISHED 7215/firefox-bin
yonami.local:58829      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:46025      208.50.77.78:www        ESTABLISHED 7215/firefox-bin
yonami.local:46001      208.50.77.78:www        ESTABLISHED 7215/firefox-bin
yonami.local:41860      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
yonami.local:45853      pv-in-f100.1e100.ne:www ESTABLISHED 7215/firefox-bin
yonami.local:45339      px-in-f102.1e100.ne:www ESTABLISHED 7215/firefox-bin
yonami.local:58807      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:58801      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:41861      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
yonami.local:41864      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
yonami.local:41862      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
yonami.local:41863      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
yonami.local:58808      cdce.sef004.interna:www ESTABLISHED 7215/firefox-bin
yonami.local:56984      185-131.amazon.com:www  ESTABLISHED 7215/firefox-bin
yonami.local:52057      208.50.77.72:www        ESTABLISHED 7215/firefox-bin
yonami.local:41865      208.50.77.95:www        ESTABLISHED 7215/firefox-bin
&lt;/pre&gt;
&lt;p&gt;This was especially peculiar, because the only Firefox window I had open was to some totally static webpage. No Comet or other JavaScript funny-business going on there. No other Firefox tabs or windows open. So what the hell are all these other connections?&lt;/p&gt;
&lt;p&gt;Googling reveals that 1e100.net are Google servers and that Firefox may have connections open to these to do Safebrowsing or other random bits. The others are mysterious: cdce.sef004.internap.net is probably some Internap CDN service, the 208.50.77.xx addresses all live behind verio-1.ar5.SEA1.gblx.net, and look like Akami servers. 185-131.amazon.com doesn’t even forward resolve (I didn’t save a copy of the &lt;code&gt;netstat -na&lt;/code&gt; output).&lt;/p&gt;
&lt;p&gt;Nothing looks especially nefarious, but why would I have so many lingering established connections? Surely if I close a tab, Firefox closes all keep-alive connections originating from that tab. Of course, when I killed Firefox, the network activity stopped.&lt;/p&gt;
&lt;p&gt;Meanwhile, Chrome was running with tabs open to Gmail, another Gmail and Google Calendar. It’s open connections were explicable and substantially fewer:&lt;/p&gt;
&lt;pre&gt;
yonami.local:45460      pv-in-f83.1e100.net:www ESTABLISHED 3002/google-chrome
yonami.local:43754      pv-in-f139.1e100.:https ESTABLISHED 3002/google-chrome
yonami.local:49226      pv-in-f83.1e100.n:https ESTABLISHED 3002/google-chrome
yonami.local:35690      pv-in-f17.1e100.n:https ESTABLISHED 3002/google-chrome
yonami.local:40323      pv-in-f83.1e100.net:www ESTABLISHED 3002/google-chrome
&lt;/pre&gt;
&lt;p&gt;I won’t even start on Firefox’s memory utilization “patterns”. Either way, score another point for Chrome’s process-per-tab resource management model.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Better symlink behavior for Git and Mercurial</title>
   <link href="http://samskivert.com/blog/2010/09/better-symlink-behavior-for-git-and-mercurial/"/>
   <updated>2010-09-11T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/better-symlink-behavior-for-git-and-mercurial</id>
   <content type="html">&lt;p&gt;Like most developers, you probably don&amp;#8217;t like unnecessary typing. By that, I don&amp;#8217;t mean the static and dynamic variety, but the fingers on keyboard variety. However, when it comes to manipulating files via version control, we have recently taken a step backward.&lt;/p&gt;

&lt;p&gt;Historically, when faced with paths that look like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;src/main/java/com/company/project/foopkg/MyAwesomeFoo.java
src/main/java/com/company/project/barpkg/MyAwesomeBar.java
src/main/java/com/company/project/bazpkg/MyAwesomeBaz.java
src/test/java/com/company/project/foopkg/MyAwesomeFooTest.java&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have created symlinks at the top-level of my project as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% ln -s src/main/java/com/company/project code
% ln -s src/test/java/com/company/project tcode&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allows me to do things like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% svn diff code/foopkg/MyAwesomeFoo.java&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is reasonably concise and fairly tab-completion-friendly. Subversion happily expands the symlink and just does the right thing. Great.&lt;/p&gt;

&lt;p&gt;Enter Git and Mercurial. For not entirely explicable reasons (save yourself the pain of Googling “git symlinks” or “hg symlinks” and perusing the results; it&amp;#8217;s a wasteland of madness), they behave as follows in such circumstances:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% git diff code/foopkg/MyAwesomeFoo.java
(tumbleweeds)
% hg diff code/foopkg/MyAwesomeFoo.java
abort: path &amp;#39;code/foopkg/MyAwesomeFoo.java&amp;#39; traverses symbolic link &amp;#39;code&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Git is especially disingenuous in simply reporting that there are no diffs. At least if you try to do something like commit a file that&amp;#8217;s on the other end of a symlink it complains:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% git commit code/foopkg/MyAwesomeFoo.java
error: pathspec &amp;#39;code/foopkg/MyAwesomeFoo.java&amp;#39; did not match any file(s) known to git.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, what we really want these tools to do is DWIM: just figure out where the damned file is and do what I asked.&lt;/p&gt;

&lt;p&gt;Fortunately, both tools behave themselves when presented with fully qualified paths. I whipped up a little Perl script to hide the scary symlinks from these poor overburdened tools. I&amp;#8217;ve reproduced it here, in case you too, dear reader, find this to be an annoyance:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl -w
#
# Expands symlinks before Git/Hg sees them.

use Cwd &amp;#39;abs_path&amp;#39;;

# Will the real DVCS please stand up?
my ($x,$orig) = ($0 =~ m#^(.*/)?([^/]+)$#);
my $bin;
foreach (`which -a $orig`) {
    chomp;
    $bin = $_ unless ($_ eq $0);
}
die &amp;quot;Can&amp;#39;t find $orig binary.\n&amp;quot; unless $bin;

# Expand any symlinks in our args
my @args = ($bin);
foreach (@ARGV) {
    my ($dir, $name) = ($_ =~ m#^(.*)/([^/]+)$#);
    if ($dir &amp;amp;&amp;amp; -d $dir) {
        my $abspath = abs_path($dir);
        if ($abspath !~ m/$dir$/) {
            push @args, &amp;quot;$abspath/$name&amp;quot;;
            next;
        }
    }
    push @args, $_;
}

# Now pass the processed arglist on to the real deal
exec @args;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can stuff this into files named git and hg in your path (and &lt;code&gt;chmod a+rx&lt;/code&gt; them), or you can use more drive space and stick it in something like &lt;code&gt;dwim-dvcs&lt;/code&gt; and symlink &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;hg&lt;/code&gt; to the single file.&lt;/p&gt;

&lt;p&gt;If you are conversant in the line-noise that is Perl, you may notice that I go to the trouble of handling files that don&amp;#8217;t exist. That way if you do something like the following, it still works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% git rm code/fookpkg/MyAwesomeFoo.java
% git commit code/fookpkg/MyAwesomeFoo.java (file no longer exists at this point)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;#8217;s still possible to confuse the script (in which case it just passes your arguments through as-is to git/hg), but at least you have to go further out of your way to cut yourself on that edge case.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Why Maven Sucks: Act I, Reprise</title>
   <link href="http://samskivert.com/blog/2010/09/why-maven-sucks-act-i-reprise/"/>
   <updated>2010-09-10T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/why-maven-sucks-act-i-reprise</id>
   <content type="html">&lt;p&gt;The XML insanity of passing compiler arguments to Maven like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;compilerArguments&amp;gt;
  &amp;lt;Xlint/&amp;gt;
  &amp;lt;Xlint:-serial/&amp;gt;
  &amp;lt;Xlint:-path/&amp;gt;
&amp;lt;/compilerArguments&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;has not surprisingly, come back to bite me in the ass. Most normal Maven actions seem to have no problem with it, but when I try to actually publish my project (via &lt;code&gt;mvn release:prepare&lt;/code&gt;), I get the error I expected to see all along:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error reading POM: Error on line 104: The prefix &amp;quot;Xlint&amp;quot; for element &amp;quot;Xlint:-serial&amp;quot; is not bound.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This inspired further investigation into this problem. &lt;em&gt;Surely&lt;/em&gt; among the thousands of projects built with Maven, someone else is trying to pass one of javac&amp;#8217;s myriad options that include a colon (e.g. &lt;code&gt;-proc:only, -Xlint:-foo,
-g:lines, -Xprefer:source, -Xbootclasspath/p:...,&lt;/code&gt; etc.).&lt;/p&gt;

&lt;p&gt;I eventually found &lt;a href='http://web.archive.org/web/20100923154949/http://jira.codehaus.org/browse/MCOMPILER-62'&gt;this improvement request&lt;/a&gt;, which has remained unresolved for three years! Is passing arguments to the compiler not one of the most fundamental things a build system has to do? Even make gets that right.&lt;/p&gt;

&lt;p&gt;Someone even submitted a patch in November &amp;#8216;09 to make &lt;code&gt;&amp;lt;compilerArgument&amp;gt;&lt;/code&gt; work as advertised. It has not been applied. The issue has not been assigned to anyone. As far as I can tell the Maven developers are not even aware that this is a problem. I&amp;#8217;m not even sure these “Maven developers” actually exist. More likely, Skynet sent Maven down to slowly sap the will of the programmers that created it, ensuring that they never render it obsolete by releasing a newer version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I&amp;#8217;ve since discovered that this seems to be the practiced workaround:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;fork&amp;gt;true&amp;lt;/fork&amp;gt;
&amp;lt;compilerArgument&amp;gt;-Xlint&amp;quot; &amp;quot;-Xlint:-serial&amp;quot; &amp;quot;-Xlint:-path&amp;lt;/compilerArgument&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yes. Really.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Better symlink behavior for Git and Mercurial</title>
   <link href="http://samskivert.com/blog/2010/09/better-symlink-behavior-for-git-and-mercurial/"/>
   <updated>2010-09-10T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/better-symlink-behavior-for-git-and-mercurial</id>
   <content type="html">&lt;p&gt;Like most developers, you probably don’t like unnecessary typing. By that, I don’t mean the static and dynamic variety, but the fingers on keyboard variety. However, when it comes to manipulating files via version control, we have recently taken a step backward.&lt;/p&gt;
&lt;p&gt;Historically, when faced with paths that look like the following:&lt;/p&gt;
&lt;pre&gt;
src/main/java/com/company/project/foopkg/MyAwesomeFoo.java
src/main/java/com/company/project/barpkg/MyAwesomeBar.java
src/main/java/com/company/project/bazpkg/MyAwesomeBaz.java
src/test/java/com/company/project/foopkg/MyAwesomeFooTest.java
&lt;/pre&gt;
&lt;p&gt;I have created symlinks at the top-level of my project as follows:&lt;/p&gt;
&lt;pre&gt;
% ln -s src/main/java/com/company/project code
% ln -s src/test/java/com/company/project tcode
&lt;/pre&gt;
&lt;p&gt;This allows me to do things like:&lt;/p&gt;
&lt;pre&gt;
% svn diff code/foopkg/MyAwesomeFoo.java
&lt;/pre&gt;
&lt;p&gt;which is reasonably concise and fairly tab-completion-friendly. Subversion happily expands the symlink and just does the right thing. Great.&lt;/p&gt;
&lt;p&gt;Enter Git and Mercurial. For not entirely explicable reasons (save yourself the pain of Googling “git symlinks” or “hg symlinks” and perusing the results; it’s a wasteland of madness), they behave as follows in such circumstances:&lt;/p&gt;
&lt;pre&gt;
% git diff code/foopkg/MyAwesomeFoo.java
(tumbleweeds)
% hg diff code/foopkg/MyAwesomeFoo.java
abort: path 'code/foopkg/MyAwesomeFoo.java' traverses symbolic link 'code'
&lt;/pre&gt;
&lt;p&gt;Git is especially disingenuous in simply reporting that there are no diffs. At least if you try to do something like commit a file that’s on the other end of a symlink it complains:&lt;/p&gt;
&lt;pre&gt;
% git commit code/foopkg/MyAwesomeFoo.java
error: pathspec 'code/foopkg/MyAwesomeFoo.java' did not match any file(s) known to git.
&lt;/pre&gt;
&lt;p&gt;However, what we really want these tools to do is DWIM: just figure out where the damned file is and do what I asked.&lt;/p&gt;
&lt;p&gt;Fortunately, both tools behave themselves when presented with fully qualified paths. I whipped up a little Perl script to hide the scary symlinks from these poor overburdened tools. I’ve reproduced it here, in case you too, dear reader, find this to be an annoyance:&lt;/p&gt;
&lt;pre&gt;
#!/usr/bin/perl -w
#
# Expands symlinks before Git/Hg sees them.

use Cwd &amp;#39;abs_path&amp;#39;;

# Will the real DVCS please stand up?
my ($x,$orig) = ($0 =~ m#^(.*/)?([^/]+)$#);
my $bin;
foreach (`which -a $orig`) {
    chomp;
    $bin = $_ unless ($_ eq $0);
}
die &amp;quot;Can&amp;#39;t find $orig binary.\n&amp;quot; unless $bin;

# Expand any symlinks in our args
my @args = ($bin);
foreach (@ARGV) {
    my ($dir, $name) = ($_ =~ m#^(.*)/([^/]+)$#);
    if ($dir &amp;amp;&amp;amp; -d $dir) {
        my $abspath = abs_path($dir);
        if ($abspath !~ m/$dir$/) {
            push @args, &amp;quot;$abspath/$name&amp;quot;;
            next;
        }
    }
    push @args, $_;
}

# Now pass the processed arglist on to the real deal
exec @args;
&lt;/pre&gt;
&lt;p&gt;You can stuff this into files named &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;hg&lt;/code&gt; in your path (and &lt;code&gt;chmod a+rx&lt;/code&gt; them), or you can use more drive space and stick it in something like &lt;code&gt;dwim-dvcs&lt;/code&gt; and symlink &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;hg&lt;/code&gt; to the single file.&lt;/p&gt;
&lt;p&gt;If you are conversant in the line-noise that is Perl, you may notice that I go to the trouble of handling files that don’t exist. That way if you do something like the following, it still works:&lt;/p&gt;
&lt;pre&gt;
% git rm code/fookpkg/MyAwesomeFoo.java
% git commit code/fookpkg/MyAwesomeFoo.java (file no longer exists at this point)
&lt;/pre&gt;
&lt;p&gt;It’s still possible to confuse the script (in which case it just passes your arguments through as-is to &lt;code&gt;git/hg&lt;/code&gt;), but at least you have to go further out of your way to cut yourself on that edge case.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why Maven Sucks: Halftime Show</title>
   <link href="http://samskivert.com/blog/2010/09/why-maven-sucks-halftime-show/"/>
   <updated>2010-09-09T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/why-maven-sucks-halftime-show</id>
   <content type="html">&lt;p&gt;One can, and is indeed encouraged to, sign one&amp;#8217;s Maven artifacts with GPG. This involves generating an &lt;code&gt;artifact-version.jar.asc&lt;/code&gt; file containing the ASCII representation of the cryptographic signature for the artifact in question. This is uploaded to the Maven repository along with the artifact.&lt;/p&gt;

&lt;p&gt;Maven then helpfully generates &lt;code&gt;artifact-version.jar.asc.md5&lt;/code&gt; and &lt;code&gt;artifact-version.jar.asc.sha1&lt;/code&gt;, and uploads those to the repository as well. I don&amp;#8217;t need one, let alone two, cryptographic hashes to tell me that my cryptographic signature has not been tampered with. This is no doubt because Maven generates cryptographic hashes for everything that goes into the repository, but the result seems somewhat comical.&lt;/p&gt;

&lt;p&gt;I tried to track down the reason for generating hashes with two different algorithms, but the commit that introduces the change is cryptic:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[MINSTALL-34] update dependencies and correct build.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I can only assume that this was a design by committee decision of some sort.&lt;/p&gt;

&lt;p&gt;While I was perusing the commit logs, I saw that someone else shared my opinion about the utility of hashing signatures:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;r630088 | wsmoak | 2008-02-21 20:27:13 -0800 (Thu, 21 Feb 2008) | 3 lines

[MINSTALL-48] Don&amp;#39;t create checksums for gpg signature files
Submitted by: Niall Pemberton&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I can only assume that my maven-install-plugin is defaulting to some version that&amp;#8217;s more than two and a half years old because I haven&amp;#8217;t gone out of my way to add five lines of boilerplate to my POM to ensure that I&amp;#8217;m using the latest version of a plugin that I had never heard of until I undertook this investigation.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Why Maven Sucks: Act III</title>
   <link href="http://samskivert.com/blog/2010/09/why-maven-sucks-act-iii/"/>
   <updated>2010-09-08T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/why-maven-sucks-act-iii</id>
   <content type="html">&lt;p&gt;The saga (&lt;a href='/blog/2010/09/why-maven-sucks-act-i/'&gt;act i&lt;/a&gt;, &lt;a href='/blog/2010/09/why-maven-sucks-act-ii/'&gt;act ii&lt;/a&gt;) continues.&lt;/p&gt;

&lt;p&gt;More reasons why Maven sucks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Plugin version handling sucks.&lt;/p&gt;

&lt;p&gt;I learned this when I was trying to get Maven to generate javadocs. I was configuring the Maven Javadoc plugin with links to external javadocs when I discovered the very handy &lt;code&gt;detectJavaApiLink&lt;/code&gt; option. It automatically adds a link to the standard Java API javadocs whose version matches the version specified in the &lt;code&gt;-source&lt;/code&gt; argument to your compilation.&lt;/p&gt;

&lt;p&gt;Imagine my chagrin when I discovered that it was not working. I tried enabling it manually, even though it claims to be enabled by default. I then ran Maven with debugging output to see if it would report what options it was passing to the javadoc tool, and happened to notice that &lt;code&gt;detectJavaApiLink&lt;/code&gt; didn&amp;#8217;t appear at all in the dump of the plugin configuration.&lt;/p&gt;

&lt;p&gt;This inspired me to investigated the documentation and see that this option was added in version 2.6 of the plugin. I inspected my debugging output and saw that I had version 2.5. I had already chafed against the fact that all of the documentation I saw for Maven on the web contained POM snippets with arbitrary and almost universally out of date versions for the plugins. My solution to this was to simply remove the &lt;code&gt;&amp;lt;version&amp;gt;&lt;/code&gt; element entirely from my plugin declarations.&lt;/p&gt;

&lt;p&gt;I assumed, foolishly, that this would cause Maven to use the latest version of the plugins. In fact, it seems to use some arbitrary version. My POM inherits from a POM which actually references version 2.7 of the javadoc plugin, so I have no idea where it&amp;#8217;s getting version 2.5. Perhaps it is some transitive dependency of some other plugin whose version number I have not specified.&lt;/p&gt;

&lt;p&gt;Further research into this matter revealed that I can specify &lt;code&gt;RELEASE&lt;/code&gt; as a version and get the latest release version. Peachy. However, this is considered bad form by the Maven community because it may cause problems with your build if plugins decide to change the default values of their options. Is this really such a big problem that it&amp;#8217;s better to have everyone expend the effort to periodically manually upgrade their dozens of Maven plugins in their dozens of builds? Furthermore, is it such a big problem that it&amp;#8217;s worth having tens of thousands of web pages filled with instructions on how to do X or Y with Maven, all filled with ancient version numbers just waiting to bite newbie/lazy/tired Maven users in the ass?&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s additionally annoying that all of the plugins implicitly included in your build are of some arbitrary version. If you want the latest version of those, you have to add to your already dangerously obese POM file an additional 5 lines of boilerplate for each plugin you wish to keep up to date.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Maven could have magically handled Javadoc dependencies, but didn&amp;#8217;t.&lt;/p&gt;

&lt;p&gt;I also noticed, while poring over the documentation for the javadoc plugin, an option entitled &lt;code&gt;detectLinks&lt;/code&gt;, which purports to automatically add &lt;code&gt;-link&lt;/code&gt; arguments for the projects on which your project depends. Awesome! A longstanding annoyance with javadoc is that you have to manually configure it with URLs for every project whose types you reference in your own project so that it correctly links those types in the generated documentation.&lt;/p&gt;

&lt;p&gt;Maven goes to all this trouble to collect project metadata and publish it along with the project&amp;#8217;s artifacts. They &lt;em&gt;must&lt;/em&gt; have included the project&amp;#8217;s javadoc API url among that metadata, and that is what &lt;code&gt;detectLinks&lt;/code&gt; is using to automatically wire up the documentation.&lt;/p&gt;

&lt;p&gt;Nope. They did nothing nearly so useful. One of Maven&amp;#8217;s dead-on-arrival ideas from the early days was that it could generate a cookie-cutter website for your project, full of a bunch of boilerplate crap. In generating such websites, it would put your API documentation at &lt;code&gt;${project.url}/apidocs&lt;/code&gt;, and that&amp;#8217;s exactly where the javadoc plugin expects to find the API docs for all of your dependent projects.&lt;/p&gt;

&lt;p&gt;You can take a guess at how many of my dependent projects have their API documentation at that URL. I&amp;#8217;ll give you a hint, you can count the number on zero hands.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Why Maven Sucks: Act II</title>
   <link href="http://samskivert.com/blog/2010/09/why-maven-sucks-act-ii/"/>
   <updated>2010-09-08T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/why-maven-sucks-act-ii</id>
   <content type="html">&lt;p&gt;Sun, in their infinite wisdom, circa Java 1.3, extended the jar file specification to allow dependencies to be expressed inside jar files by adding a &lt;a href='http://download.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Main%20Attributes'&gt;Class-Path&lt;/a&gt; attribute to the &lt;code&gt;MANIFEST.MF&lt;/code&gt; file. This causes the JVM (and javac, and various app servers) to try to magically add dependent jar files to the classpath. This is half-assed and wrong in too many ways to enumerate here.&lt;/p&gt;

&lt;p&gt;Some other enthusiastic Sun engineer then helpfully added &lt;code&gt;activation.jar&lt;/code&gt; to &lt;code&gt;mail.jar&lt;/code&gt;&amp;#8217;s Class-Path attribute, under the multiple misguided assumptions that no one would ever possibly need to use &lt;code&gt;mail.jar&lt;/code&gt; without also having &lt;code&gt;activation.jar&lt;/code&gt; in their classpath, with precisely that name, and located in precisely the same directory. Great.&lt;/p&gt;

&lt;p&gt;Maven then upped the ante on this little fiasco by deciding that any time the Java compiler generates a warning that they can&amp;#8217;t parse, they should fail the build. Clearly it&amp;#8217;s critical that your build system be conversant in every possible warning that might be emitted by your compiler. As a result, when I fix their boneheaded decision to suppress warnings by default, my build now fails with this demonstration of awesomeness:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
could not parse error message: warning: [path] bad path element
&amp;quot;/home/mdb/.m2/repository/javax/mail/mail/1.4.1/activation.jar&amp;quot;: no such file or directory
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Thank you Sun, and thank you Maven.&lt;/p&gt;

&lt;p&gt;For those of you arriving from the Googles and looking for a solution to this problem, it is as follows: pass &lt;code&gt;-Xlint:-path&lt;/code&gt; to javac to prevent it from issuing a warning when it cannot find &lt;code&gt;activation.jar&lt;/code&gt;. If you will be passing this compiler argument via Maven, be sure to read &lt;a href='/blog/2010/09/why-maven-sucks-act-i/'&gt;Why Maven Sucks: Act I&lt;/a&gt; before doing so, to avoid the various pitfalls that await.&lt;/p&gt;

&lt;p&gt;I should further mention the irony that &lt;code&gt;activation.jar&lt;/code&gt; is listed as a dependency of &lt;code&gt;mail.jar&lt;/code&gt;, but it&amp;#8217;s being placed in &lt;code&gt;.m2/repository/javax/activation/activation/1.1/activation-1.1.jar&lt;/code&gt; which is where Maven wants it and not where the utility deficient &lt;code&gt;Class-Path&lt;/code&gt; mechanism expects it to be.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Why Maven Sucks: Act I</title>
   <link href="http://samskivert.com/blog/2010/09/why-maven-sucks-act-i/"/>
   <updated>2010-09-08T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/09/why-maven-sucks-act-i</id>
   <content type="html">&lt;p&gt;These ruminations were languishing in commit messages, which would normally satisfy my urge to complain. But now I need to complain further, and don&amp;#8217;t have a commit message in which to express my discontent, so I&amp;#8217;m airing the whole basket of dirty laundry here, and going on the record as a Maven hater. For those of you privy to the original commit messages, my new complaints will be aired in Act III. Now then, on with the show.&lt;/p&gt;

&lt;p&gt;Reasons that Maven sucks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Warnings and deprecations are not shown by default.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Documentation shows use of &lt;code&gt;&amp;lt;compilerArgument&amp;gt;&lt;/code&gt; with multiple arguments in a single element:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;compilerArgument&amp;gt;-foo -bar&amp;lt;/compilerArgument&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which is a bald-faced lie. Only a single argument is allowed inside a &lt;code&gt;&amp;lt;compilerArgument&amp;gt;&lt;/code&gt; element. If you try to use multiple arguments, you see that it uselessly tries to pass everything as a single argument:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Failure executing javac, but could not parse the error:
 javac: invalid flag: -foo -bar
 Usage: javac &amp;lt;options&amp;gt; &amp;lt;source files&amp;gt;
 use -help for a list of possible options&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Bear in mind that -foo and -bar were actual javac arguments, not the stand-ins I&amp;#8217;m using here. I&amp;#8217;m saving the real arguments for a punchline below.)&lt;/p&gt;

&lt;p&gt;Web search turns up “helpful” advice to use multiple elements:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;compilerArgument&amp;gt;-foo&amp;lt;/compilerArgument&amp;gt;
 &amp;lt;compilerArgument&amp;gt;-bar&amp;lt;/compilerArgument&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Fair enough, but also a bald-faced lie. After spending a bunch of time debugging why my compiler arguments were not working, I discovered that Maven was just (silently) using the last one and ignoring/overwriting all of the previous arguments.&lt;/p&gt;

&lt;p&gt;I had noticed while perusing &lt;a href='http://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html'&gt;the documentation&lt;/a&gt; that it was also possible to use the so-called “Map version” (whatever that means), which uses this completely stupid syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;compilerArguments&amp;gt;
   &amp;lt;foo/&amp;gt;
   &amp;lt;bar/&amp;gt;
 &amp;lt;/compilerArguments&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why is that syntax completely stupid, you might ask? Well, dear reader, because the arguments that I&amp;#8217;m actually passing are the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;compilerArguments&amp;gt;
   &amp;lt;Xlint/&amp;gt;
   &amp;lt;Xlint:-serial/&amp;gt;
 &amp;lt;/compilerArguments&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is a case study in how not to represent information in XML. I didn&amp;#8217;t even try that originally because I was sure that it would not work, given the wacky non-&lt;code&gt;[a-zA-z]+&lt;/code&gt; nature of the argument I needed to supply. The fact that it does work gives me the fear. You might think the same thing &lt;a href='http://bungleton.com/'&gt;Charlie&lt;/a&gt; did, when he replied to my original commit message:&lt;/p&gt;

&lt;p&gt;&amp;gt; Doesn&amp;#8217;t that create an element named -serial in the Xlint namespace?&lt;/p&gt;

&lt;p&gt;Apparently not, because it works.&lt;/p&gt;

&lt;p&gt;You might also wonder, like I did, whether the following form would provide satisfaction:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;compilerArguments&amp;gt;
   &amp;lt;compilerArgument&amp;gt;-Xlint&amp;lt;/compilerArgument&amp;gt;
   &amp;lt;compilerArgument&amp;gt;-Xlint:-serial&amp;lt;/compilerArgument&amp;gt;
 &amp;lt;/compilerArguments&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By being absurdly verbose, it seems right in line with The Maven Way&amp;#8482;. However, that results in &lt;code&gt;-compilerArgument=-Xlint&lt;/code&gt; and &lt;code&gt;-compilerArgument=-Xlint:-serial&lt;/code&gt; being passed to the compiler. Hilarity naturally ensues.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Shoot me now</title>
   <link href="http://samskivert.com/blog/2010/08/shoot-me-now/"/>
   <updated>2010-08-25T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/08/shoot-me-now</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m foolishly trying to write a javac annotation processor in Scala. This has already been a road fraught with gratuitous obstacles, but the latest wrinkle has driven me to vent in public.&lt;/p&gt;

&lt;p&gt;When I run my annotation processor thusly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javac -processor FooProcessor -processorpath fooproc/classes:blah/scala-library.jar SomeFile.java&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I get &lt;code&gt;java.lang.IllegalStateException: zip file closed&lt;/code&gt; when my processor tries to load Scala classes. But if I &lt;code&gt;unpack scala-library.jar&lt;/code&gt; into &lt;code&gt;fooproc/classes&lt;/code&gt; then it works. Joy! Somehow the &lt;code&gt;scala-library.jar&lt;/code&gt; file causes javac to choke.&lt;/p&gt;

&lt;p&gt;I of course tried repacking the jar file, in case perhaps something in the stock &lt;code&gt;scala-library.jar&lt;/code&gt; was weird, but using the repacked version still failed with &lt;code&gt;zip file closed&lt;/code&gt;. What&amp;#8217;s even more awesome is that javac 1.6 does not have a problem with &lt;code&gt;scala-library.jar&lt;/code&gt;, only javac 1.7.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Euler 2⁶</title>
   <link href="http://samskivert.com/blog/2010/08/euler-2%25e2%2581%25b6/"/>
   <updated>2010-08-25T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/08/euler-2%e2%81%b6</id>
   <content type="html">&lt;p&gt;&lt;a href='http://projecteuler.net/index.php?section=problems&amp;amp;id=64'&gt;Problem 064&lt;/a&gt;: (&lt;a href='http://github.com/samskivert/euler-scala/raw/master/Euler064.scala'&gt;source&lt;/a&gt;):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='k'&gt;object&lt;/span&gt; &lt;span class='nc'&gt;Euler064&lt;/span&gt; &lt;span class='k'&gt;extends&lt;/span&gt; &lt;span class='nc'&gt;EulerApp&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Root&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;add&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;div&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;expand&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;term&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;((&lt;/span&gt;&lt;span class='n'&gt;math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sqrt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;add&lt;/span&gt;&lt;span class='o'&gt;)/&lt;/span&gt;&lt;span class='n'&gt;div&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;toInt&lt;/span&gt;
      &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;nadd&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;term&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;div&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;add&lt;/span&gt;
      &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;term&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nc'&gt;Root&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;nadd&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;nadd&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;nadd&lt;/span&gt;&lt;span class='o'&gt;)/&lt;/span&gt;&lt;span class='n'&gt;div&lt;/span&gt;&lt;span class='o'&gt;))&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;override&lt;/span&gt; &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;toString&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;(â&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;root&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;+&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;add&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;)/&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;div&lt;/span&gt;
  &lt;span class='o'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;expansion&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;terms&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;List&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;],&lt;/span&gt; &lt;span class='n'&gt;roots&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;List&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Root&lt;/span&gt;&lt;span class='o'&gt;])&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;List&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;term&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='n'&gt;roots&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;head&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expand&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;div&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='n'&gt;roots&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;contains&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;))&lt;/span&gt; &lt;span class='n'&gt;term&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt; &lt;span class='n'&gt;terms&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='n'&gt;expansion&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;term&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt; &lt;span class='n'&gt;terms&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;root&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt; &lt;span class='n'&gt;roots&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
  &lt;span class='o'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;answer&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='n'&gt;to&lt;/span&gt; &lt;span class='mi'&gt;10000&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;expansion&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='nc'&gt;Nil&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nc'&gt;Root&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)::&lt;/span&gt;&lt;span class='nc'&gt;Nil&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;length&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;_%&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;==&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here we have a nice little case class to represent a single step in the infinite expansion. The process of generating the next expansion could be done purely with simple arithmetic, but I&amp;#8217;m lazy, so I just use &lt;code&gt;math.sqrt&lt;/code&gt; to obtain the non-fractional part. I don&amp;#8217;t actually need to keep track of the terms to obtain the solution, but it was handy to have when I was validating the solution, so I kept it around. Same goes for &lt;code&gt;toString&lt;/code&gt;. I just love that little root sign!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Euler 63</title>
   <link href="http://samskivert.com/blog/2010/08/euler-63/"/>
   <updated>2010-08-21T00:00:00-07:00</updated>
   <id>http://samskivert.com/blog/2010/08/euler-63</id>
   <content type="html">&lt;p&gt;&lt;a href='http://projecteuler.net/index.php?section=problems&amp;amp;id=63'&gt;Problem 063&lt;/a&gt;: (&lt;a href='http://github.com/samskivert/euler-scala/raw/master/Euler063.scala'&gt;source&lt;/a&gt;):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='scala'&gt;&lt;span class='k'&gt;object&lt;/span&gt; &lt;span class='nc'&gt;Euler063&lt;/span&gt; &lt;span class='k'&gt;extends&lt;/span&gt; &lt;span class='nc'&gt;EulerApp&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;pows&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='kt'&gt;Int&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Stream&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;from&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;prefixLength&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='k'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;BigInt&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;pow&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;).&lt;/span&gt;&lt;span class='n'&gt;toString&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;length&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='n'&gt;answer&lt;/span&gt; &lt;span class='k'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='n'&gt;to&lt;/span&gt; &lt;span class='mi'&gt;9&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pows&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='n'&gt;sum&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The main observation here is that the number of digits of &lt;em&gt;a&lt;/em&gt;&lt;sup&gt;&lt;em&gt;x&lt;/em&gt;&lt;/sup&gt;, for &lt;em&gt;a&lt;/em&gt; ≥ 10, is guaranteed to exceed &lt;em&gt;x&lt;/em&gt;. So we can restrict ourselves to looking only at the numbers from 1 to 9. Furthermore, the number of digits of &lt;em&gt;a&lt;/em&gt;&lt;sup&gt;&lt;em&gt;x&lt;/em&gt;&lt;/sup&gt;, for 1 ≤ &lt;em&gt;a&lt;/em&gt; ≤ 9, will equal &lt;em&gt;x&lt;/em&gt; up to some maximum &lt;em&gt;x&lt;/em&gt;, and then be less than &lt;em&gt;x&lt;/em&gt; for all higher &lt;em&gt;x&lt;/em&gt;. That enough &lt;em&gt;x&lt;/em&gt;s for you?&lt;/p&gt;</content>
 </entry>
 

</feed>

