<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Matt Brubeck</title>
 <link href="http://limpet.net/mbrubeck/atom.xml" rel="self"/>
 <link href="http://limpet.net/mbrubeck/"/>
 <updated>2010-03-12T11:58:36-08:00</updated>
 <id>http://limpet.net/mbrubeck/</id>
 <author>
   <name>Matt Brubeck</name>
   <email>mbrubeck@limpet.net</email>
   <uri>http://limpet.net/mbrubeck/</uri>
 </author>
 <icon>images/mbrubeck.jpg</icon>

 
 
 <entry>
   <title>Discovering Urbit: Functional programming from scratch</title>
   <link href="http://limpet.net/mbrubeck/2010/03/12/urbit.html"/>
   <updated>2010-03-12T00:00:00-08:00</updated>
   <id>http://limpet.net/mbrubeck//2010/03/12/urbit</id>
   <content type="html">&lt;p&gt;C. Guy Yarvin is a &amp;ldquo;&lt;em&gt;good&lt;/em&gt; friend&amp;rdquo; of &lt;a href=&quot;http://unqualified-reservations.blogspot.com/&quot;&gt;Mencius Moldbug&lt;/a&gt;, a
pseudonymous blogger known for iconoclastic novella-length essays on
politics and history (and occasionally &lt;a href=&quot;http://unqualified-reservations.blogspot.com/2007/08/whats-wrong-with-cs-research.html&quot;&gt;computer science&lt;/a&gt;).  Guy recently
&lt;a href=&quot;http://moronlab.blogspot.com/&quot;&gt;published&lt;/a&gt;, under his own name, a project in language and
systems design.  His own writing about his work is entertaining but verbose
(as Moldbug's readers might expect), so I will attempt to summarize it here.&lt;/p&gt;

&lt;h1&gt;Nock, Urbit, Watt&lt;/h1&gt;

&lt;p&gt;First there is &lt;a href=&quot;http://moronlab.blogspot.com/2010/01/nock-maxwells-equations-of-software.html&quot;&gt;Nock&lt;/a&gt;, &lt;em&gt;&amp;ldquo;a tool for defining higher-level languages &amp;ndash;
comparable to the lambda calculus, but meant as foundational system software
rather than foundational meta&amp;shy;mathe&amp;shy;matics.&amp;rdquo;&lt;/em&gt;  Its primitives include positive
integers with equality and increment operators, cons cells with
car/cdr/cadr/etc., and a macro for convenient branching.  Nock uses trees of
integers to represent both code and data.  Nock is aggressively tiny; the spec
linked above is just 33 terse lines.&lt;/p&gt;

&lt;p&gt;Next, Guy provides the rationale for Nock.  In short, he asks how a
planet-wide computing infrastructure (OS, networking, and languages)
would look if designed from first priniciples for robustness and
interoperability.  The answer he proposes is &lt;a href=&quot;http://moronlab.blogspot.com/2010/01/urbit-functional-programming-from.html&quot;&gt;Urbit&lt;/a&gt;: a URI-like name&amp;shy;space
distributed globally via &lt;a href=&quot;http://www.parc.com/publication/2318/networking-named-content.html&quot;&gt;content-centric networking&lt;/a&gt;, with a &lt;a href=&quot;http://github.com/cgyarvin/urbit/blob/master/Spec/urbit/3-intro.txt&quot;&gt;feudal
structure&lt;/a&gt; for top-level names and cryptographic identities.
Urbit is a &lt;em&gt;static functional name&amp;shy;space:&lt;/em&gt; it is both referentially
transparent and monotonic (a name, once bound to a value, cannot be un- or
re-bound).&lt;/p&gt;

&lt;p&gt;Why does this require a new formal logic and a new programming language? In
Urbit, all data &lt;em&gt;and code&lt;/em&gt; are distributed via the global namespace.  For
interoperability, the code must have a standard format.  Nock's minimal spec
is meant to be an un&amp;shy;ambiguous, unchanging, totally standardized basis
for computation in Urbit.  Above it will be &lt;a href=&quot;http://github.com/cgyarvin/urbit/blob/master/Spec/watt/anatomy.txt&quot;&gt;Watt&lt;/a&gt;, a self-hosting language
that compiles to Nock.  Urbit itself will be implemented in Watt, so Nock and
Watt are designed to treat data as code using &lt;a href=&quot;http://github.com/cgyarvin/urbit/blob/master/Spec/urbit/5-whynock.txt&quot;&gt;metacircular evaluation&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;The code&lt;/h1&gt;

&lt;p&gt;A prototype &lt;a href=&quot;http://github.com/cgyarvin/urbit/tree/master&quot;&gt;implementation&lt;/a&gt; of Watt is on GitHub.  It is not yet
self-hosting; the current compiler is written in C.  Watt is a functional
language with static types called &amp;ldquo;molds&amp;rdquo; and a mechanism for
explicit lazy evaluation.  (I was suprised to find I had accidentally created
an in&amp;shy;com&amp;shy;patible lazy dialect of Nock &amp;ndash; despite its goal of
unambiguous semantics &amp;ndash; just by &lt;a href=&quot;http://github.com/mbrubeck/mynock&quot;&gt;implementing it in Haskell&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;The code is not fully documented, but the repository contains draft &lt;a href=&quot;http://github.com/cgyarvin/urbit/tree/master/Spec&quot;&gt;specs&lt;/a&gt; for
both Watt and Urbit.  Beware: the syntax and terminology are a bit
unconventional.  Guy has offered a few exercises to help get started with Nock
and Watt:&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;The Nock &lt;a href=&quot;http://moronlab.blogspot.com/2010/01/nock-maxwells-equations-of-software.html&quot;&gt;challenge&lt;/a&gt;:&lt;/dt&gt; &lt;dd&gt;Write a decrement operator in Nock, and an interpreter that can evaluate it.&lt;/dd&gt;
&lt;dt&gt;Basic Watt:&lt;/dt&gt; &lt;dd&gt;Write an integer square root function in Watt.&lt;/dd&gt;
&lt;dt&gt;Advanced Watt:&lt;/dt&gt;
&lt;dd&gt;How would you write a function that tests whether molds A and B are
orthogonal (no noun is in both A and B)?   Or compatible (any noun in A is
also in B)?  Are these functions NP-complete?  If so, how might one work
around this in practice?&lt;/dd&gt;
&lt;/dl&gt;


&lt;p&gt;If you want to learn more, start with these problems. You can email your solutions to
Guy.&lt;/p&gt;

&lt;h1&gt;Will it work?&lt;/h1&gt;

&lt;p&gt;I find Urbit intellectually appealing; it is a simple and clean architecture
that could potentially replace a lot of complex system software.  But can we
get there from here?&lt;/p&gt;

&lt;p&gt;Guy imagines Urbit as the product of an ages-old Martian civilization:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Since Earth code is fifty years old, and Martian code is fifty million years
old, Martian code has been evolving into a big ball of mud for a million
times longer than Earth software. (And two million times longer than
Windows.) &amp;hellip;&lt;/p&gt;

&lt;p&gt;Therefore, at some point in Martian history, some abject fsck of a Martian
code-monkey must have said: &lt;em&gt;fsck&lt;/em&gt; this entire fscking ball of mud. For &lt;em&gt;lo&lt;/em&gt;,
its defects cannot be summarized; for they exceed the global supply of
bullet points; for numerous as the fishes in the sea, like the fishes in the
sea they fsck, making more little fscking fishes. For lo, it is &lt;em&gt;fscked&lt;/em&gt;, and
a big ball of mud. And there is only one thing to do with it: &lt;em&gt;obliterate&lt;/em&gt; the
trunk, &lt;em&gt;fire&lt;/em&gt; the developers, and hire a whole new fscking &lt;em&gt;army&lt;/em&gt; of Martian
code-monkeys to rewrite the &lt;em&gt;entire fscking thing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&amp;hellip; This is the crucial inference we can draw about Mars: since the
Martians had 50 million years to try, in the end they must have succeeded.
The result: Martian code, as we know it today. Not enormous and horrible
&amp;ndash; &lt;em&gt;tiny and diamond-perfect&lt;/em&gt;. Moreover, because it is tiny and
diamond-perfect, it is perfectly stable and never changes or decays. It
neither is a big ball of mud, nor tends to become one. It has achieved its
final, permanent and excellent state.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Do Earthlings have the will to throw out the whole ball of mud and start from
scratch?  I doubt it.  We can build Urbit but no one will come, unless
it solves some problem radically better than current software.  Moldbug thinks
feudalism will produce &lt;a href=&quot;http://unqualified-reservations.blogspot.com/2010/03/future-of-search.html&quot;&gt;better online reputation&lt;/a&gt;, but feudal reputation
does not require feudal identity; it is not that much harder to build
Moldbug's reputation system on Earth than on Mars.  I still have not figured
out the killer app that will get early adopters to switch to Urbit.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>The network is the human being</title>
   <link href="http://limpet.net/mbrubeck/2010/03/01/network-mind.html"/>
   <updated>2010-03-01T00:00:00-08:00</updated>
   <id>http://limpet.net/mbrubeck//2010/03/01/network-mind</id>
   <content type="html">&lt;p&gt;Nathanael Boehm wrote a nice essay last month called &lt;a href=&quot;http://loungesessions.wordpress.com/2010/02/22/the-future-of-employment/&quot;&gt;The Future of
Employment?&lt;/a&gt;, about a disconnect between workers' and employers' views of
social networks.  (This post is based partly on the ensuing Hacker News
&lt;a href=&quot;http://news.ycombinator.com/item?id=1141843&quot;&gt;thread&lt;/a&gt;.)  Boehm wrote:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When I need help with a challenge at work or need to run some ideas past
people I don’t turn to my co-workers, I look to my network of colleagues
beyond the walls of my workplace. Whilst my co-workers might be competent at
their job they can’t hope to compete with the hundreds of people I have
access to through my social networks.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The late Sun Microsystems taught us that &lt;a href=&quot;http://blogs.sun.com/jonathan/entry/the_network_is_the_computer&quot;&gt;the network is the computer&lt;/a&gt;.
It's true: we still use non-networked computers for specialized tasks, but
nobody wants one on their desk &amp;ndash; it's just so useless compared to one that
talks to the entire world.  Boehm could have titled his essay &lt;em&gt;The Network is
the Employee&lt;/em&gt;.  There are still tasks that people do in isolation, but the
ability to contact a network of peers and experts makes the difference in my
job, and many others.&lt;/p&gt;

&lt;h2&gt;Alone together&lt;/h2&gt;

&lt;p&gt;The lone computer programmer in a small business has thousands of
colleagues on &lt;a href=&quot;http://stackoverflow.com/&quot;&gt;Stack Overflow&lt;/a&gt;, &lt;a href=&quot;http://www.reddit.com/&quot;&gt;Reddit&lt;/a&gt;, and so on.  It's a
messy way to find answers, but it's sure better than the days when your only choice
was to call tech support &amp;ndash; or smack the box with your fist, whichever
seemed more useful. I can't begin to list all the problems I've solved and
things I've learned by Googling for others with experience, and
getting help from a different expert for every problem.&lt;/p&gt;

&lt;p&gt;Decades before the web, computer geeks had virtual communities on mailing
lists, Usenet, and IRC.  Now every job in the world has its corresponding forum.  Even
the night clerk at the gas station has &lt;a href=&quot;http://notalwaysright.com/&quot;&gt;Not Always Right&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Teaching has long been a solitary profession.  Despite working in a
crowded classroom, teachers are isolated; they rarely have colleagues
observing or participating directly in their work.  This has such an impact
that teachers are sometimes trained in meditation or reflection techniques, to
make up for the lack of external feedback.  So I'm curious what happens when
teachers start to work together remotely the way programmers do.&lt;/p&gt;

&lt;h2&gt;You will be assimilated&lt;/h2&gt;

&lt;p&gt;Boehm's essay also reminded me of a vague sci-fi idea I've been kicking
around: the first group minds will evolve from the intersection of &lt;a href=&quot;https://www.mturk.com/mturk/welcome&quot;&gt;Mechanical
Turk&lt;/a&gt;, virtual assistants, social networking, and augmented reality.&lt;/p&gt;

&lt;p&gt;Starting around the 1990s, it was possible to instantly &quot;know&quot; any fact that
was published online.  Since then, we've increased the amount of content
online, our tools for searching it, and ways of connecting to the network.
Today we have instant access to almost any published knowledge, anywhere.&lt;/p&gt;

&lt;p&gt;There are more people on the net too, and more ways to find
and talk to them. Most of us can contact dozens of friends at any given
moment, plus friends-of-friends, co-workers, fellow members of communites like
&lt;a href=&quot;http://news.ycombinator.com/&quot;&gt;Hacker News&lt;/a&gt; or &lt;a href=&quot;http://ask.metafilter.com/&quot;&gt;MetaFilter&lt;/a&gt;, and also complete strangers.  Along with raw facts,
we have access to vast amounts of human judgement, experience, and skill.&lt;/p&gt;

&lt;p&gt;One product of this is the &quot;virtual assistant,&quot; who provides a service that was
once exclusive to high-powered executives. Now personal assistants can
work remotely (often overseas), spread costs by serving many masters, and
leverage the internet superpowers listed above. Their services are mostly
targeted at small business owners and the &lt;a href=&quot;http://www.fourhourworkweek.com/&quot;&gt;Tim Ferriss&lt;/a&gt; crowd, but I'm sure
someone soon will market virtual assistance to all sorts of
other creative workers, teachers, even stay-at-home parents.&lt;/p&gt;

&lt;p&gt;So, how long before I can touch a button to let a remote assistant
see what I'm seeing in real-time and help me make transportation plans,
translate foreign signs and speech, look up emails related to whatever I'm
doing or thinking, or even advise me on what to say? Some of these queries
will go to my circle of friends, others to the general public, and some to a
personal assistant who is paid well to keep up with my specific needs.  And
that assistant of course will subcontract portions of each job
to computer programs, legions of cheap anonymous Turkers, or his or her own
network of helpers.  At that point, I'm augmenting my own perception,
memory, and judgement with a whole network of brains that I carry around, ready
to engage with any situation I meet.&lt;/p&gt;

&lt;p&gt;If nothing else, I hope someone writes a good sci-fi thriller story in which a
rogue virtual assistant manipulates the actions of unsuspecting clients,
leading them to some unseen end.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Finding domain names with Node.js</title>
   <link href="http://limpet.net/mbrubeck/2010/01/13/si-unit-domains-node-js.html"/>
   <updated>2010-01-13T00:00:00-08:00</updated>
   <id>http://limpet.net/mbrubeck//2010/01/13/si-unit-domains-node-js</id>
   <content type="html">&lt;p&gt;I'm working on some ideas for finance or news software that deliberately
updates &lt;em&gt;infrequently&lt;/em&gt;, so it doesn't reward me for reloading it
constantly.  I came up with the name &quot;microhertz&quot; to describe the idea.  (1
microhertz ≈ once every eleven and a half days.)&lt;/p&gt;

&lt;p&gt;As usual when I think of a project name, I did some DNS searches.
Unfortunately &quot;microhertz.com&quot; is not available (but &quot;microhertz.org&quot; is).
Then I went off on a tangent and got curious about which other SI units are
available as domain names.&lt;/p&gt;

&lt;p&gt;This was the perfect opportunity to try &lt;a href=&quot;http://nodejs.org/&quot;&gt;node.js&lt;/a&gt; so I could use its
asynchronous DNS library to run dozens of lookups in parallel.  I grabbed a
list of &lt;a href=&quot;http://physics.nist.gov/cuu/Units/&quot;&gt;units and prefixes&lt;/a&gt; from NIST and wrote the following script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var dns = require(&quot;dns&quot;), sys = require('sys');

var prefixes = [&quot;yotta&quot;, &quot;zetta&quot;, &quot;exa&quot;, &quot;peta&quot;, &quot;tera&quot;, &quot;giga&quot;, &quot;mega&quot;,
  &quot;kilo&quot;, &quot;hecto&quot;, &quot;deka&quot;, &quot;deci&quot;, &quot;centi&quot;, &quot;milli&quot;, &quot;micro&quot;, &quot;nano&quot;,
  &quot;pico&quot;, &quot;femto&quot;, &quot;atto&quot;, &quot;zepto&quot;, &quot;yocto&quot;];

var units = [&quot;meter&quot;, &quot;gram&quot;, &quot;second&quot;, &quot;ampere&quot;, &quot;kelvin&quot;, &quot;mole&quot;,
  &quot;candela&quot;, &quot;radian&quot;, &quot;steradian&quot;, &quot;hertz&quot;, &quot;newton&quot;, &quot;pascal&quot;, &quot;joule&quot;,
  &quot;watt&quot;, &quot;colomb&quot;, &quot;volt&quot;, &quot;farad&quot;, &quot;ohm&quot;, &quot;siemens&quot;, &quot;weber&quot;, &quot;henry&quot;,
  &quot;lumen&quot;, &quot;lux&quot;, &quot;becquerel&quot;, &quot;gray&quot;, &quot;sievert&quot;, &quot;katal&quot;];

for (var i=0; i&amp;lt;prefixes.length; i++) {
  for (var j=0; j&amp;lt;units.length; j++) {
    checkAvailable(prefixes[i] + units[j] + &quot;.com&quot;, sys.puts);
  }
}

function checkAvailable(name, callback) {
  dns.resolve4(name).addErrback(function(e) {
    if (e.errno == dns.NXDOMAIN) callback(name);
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Out of 540 possible .com names, I found 376 that are available (and 10 more
that produced temporary DNS errors, which I haven't investigated).  Here are a
few interesting ones, with some commentary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exasecond.com  – &lt;i&gt;32 billion years&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;petasecond.com  – &lt;i&gt;32 million years&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;petawatt.com  – &lt;i&gt;can be produced for femtoseconds by powerful lasers&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;terapascal.com&lt;/li&gt;
&lt;li&gt;gigakelvin.com  – &lt;i&gt;possible temperature of picosecond flashes in sonoluminescence&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;giganewton.com  – &lt;i&gt;225 million pounds force&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;gigafarad.com&lt;/li&gt;
&lt;li&gt;kilosecond.com  – &lt;i&gt;16 minutes 40 seconds&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;kilokelvin.com  – &lt;i&gt;1340 degrees Fahrenheit&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;centiohm.com&lt;/li&gt;
&lt;li&gt;millifarad.com&lt;/li&gt;
&lt;li&gt;microkelvin.com&lt;/li&gt;
&lt;li&gt;picohertz.com  – &lt;i&gt;once every 31,689 years&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;picojoule.com&lt;/li&gt;
&lt;li&gt;femtogram.com  – &lt;i&gt;mass of a single virus&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;yoctogram.com  – &lt;i&gt;a hydrogen atom weighs 1.66 yoctograms&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;zeptomole.com  – &lt;i&gt;602 molecules&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;To get the complete list, just copy the script above to a file, and run it
like this: &lt;code&gt;node listnames.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Along the way I discovered that the API documentation for Node's &lt;code&gt;dns&lt;/code&gt; module
was out-of-date.  This is &lt;a href=&quot;http://github.com/mbrubeck/node/commit/bd4f56c8239aca12b6f7c2016bda51507ba7aec7&quot;&gt;fixed&lt;/a&gt; in my GitHub fork, and I've sent a pull
request to the author Ryan Dahl.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Weekend hack: Outline grep</title>
   <link href="http://limpet.net/mbrubeck/2010/01/12/outline-grep.html"/>
   <updated>2010-01-12T00:00:00-08:00</updated>
   <id>http://limpet.net/mbrubeck//2010/01/12/outline-grep</id>
   <content type="html">&lt;p&gt;I keep almost all of my notes and to-do lists in plain text files, so I can
edit and search them with Vim, grep, and other standard Unix tools.  I often
indent lines in these files to create a simple outline structure, and use the
&lt;code&gt;autoindent&lt;/code&gt; and &lt;code&gt;foldmethod=indent&lt;/code&gt; options to make Vim into a simple
outliner.&lt;/p&gt;

&lt;p&gt;To get useful output when searching through these outline-structured files, I
wrote a simple grep replacement.  Given a text file with a Python-style
indentation structure, &lt;code&gt;ogrep&lt;/code&gt; searches the file for a regular expression.  It
prints matching lines, with their &quot;parent&quot; lines as context.  For example, if
input.txt looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;2009-01-01
  New Year's Day!
    No work today.
    Visit with family.
2009-01-02
  Grocery store and library.
2009-01-03
  Stay home.
2009-01-04
  Back to work.
    Remember to set an alarm.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then &lt;code&gt;ogrep work input.txt&lt;/code&gt; will produce the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;2009-01-01
  New Year's Day!
    No work today.
2009-01-04
  Back to work.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can download ogrep from the &lt;a href=&quot;http://github.com/mbrubeck/outline-grep&quot;&gt;outline-grep repository&lt;/a&gt; on GitHub, or
just read the &lt;a href=&quot;http://github.com/mbrubeck/outline-grep/blob/master/OutlineGrep.lhs&quot;&gt;literate Haskell file&lt;/a&gt;.  The code is almost trivial (40
lines of code, plus imports and comments); I'm publishing it just in case
anyone else has a use for it, and because some of my friends were curious
about how I'm using Haskell.  I've now written a few &quot;real-world&quot; Haskell
programs (&lt;a href=&quot;http://limpet.net/mbrubeck/2009/10/30/compleat.html&quot;&gt;compleat&lt;/a&gt; was the first).  I'm finding Haskell very well suited
to such programs, though this particular one would be equally easy in a
language like Perl, Python, or Ruby.&lt;/p&gt;

&lt;p&gt;This is a one-off tool to fill a gap in my workflow; there are no
configuration options or useful error messages.  It would be fairly easy to
extend it, though.  For example, an option to include children (as well as
parents) of matching lines might be handy.  I recently realized that ogrep
often works for searching through source code too, which may generate some
more unexpected use cases.&lt;/p&gt;
</content>
 </entry>
 
 
 
 
 
 <entry>
   <title>Android 2.0 uses V8 JavaScript engine</title>
   <link href="http://limpet.net/mbrubeck/2009/11/06/android-v8.html"/>
   <updated>2009-11-06T00:00:00-08:00</updated>
   <id>http://limpet.net/mbrubeck//2009/11/06/android-v8</id>
   <content type="html">&lt;p&gt;Google has not yet released most of the Android 2.0 &quot;eclair&quot; source code, but they did
publish source for a very small number of components, including a &lt;a href=&quot;http://android.git.kernel.org/?p=platform/external/webkit.git;a=tree;h=refs/heads/android-2.0_r1_snapshot;hb=android-2.0_r1_snapshot&quot;&gt;WebKit
snapshot&lt;/a&gt;.  I was excited to see that the snapshot includes Google's V8
virtual machine.  (Previous Android releases used Safari's
JavaScriptCore/&quot;SquirrelFish Extreme&quot; VM.)  But without the rest of the source
tree, there was no way to build and run this on a real Android phone.  The
SDK includes a binary image that runs only in the qemu-based emulator.&lt;/p&gt;

&lt;p&gt;Today I got to try out a Motorola Droid.  Here's how its browser compares to
Android 1.6 on my HTC Dream (Android Dev Phone / T-Mobile G1) in the &lt;a href=&quot;http://v8.googlecode.com/svn/data/benchmarks/v5/run.html&quot;&gt;V8
Benchmark Suite&lt;/a&gt;:&lt;/p&gt;

&lt;table class=&quot;data&quot;&gt;
  &lt;tr&gt;&lt;th&gt;Test&lt;/th&gt;         &lt;th class=&quot;num&quot;&gt;Dream (1.6)&lt;/th&gt;            &lt;th class=&quot;num&quot;&gt;Droid (2.0)&lt;/th&gt; &lt;th class=&quot;num&quot;&gt;Change&lt;/th&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Richards&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;13.5&lt;/td&gt;             &lt;td class=&quot;num&quot;&gt;15.6&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;+16%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DeltaBlue&lt;/td&gt;    &lt;td class=&quot;num&quot;&gt;5.23&lt;/td&gt;             &lt;td class=&quot;num&quot;&gt;12.9&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;+147%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Crypto&lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;13.2&lt;/td&gt;             &lt;td class=&quot;num&quot;&gt;10.9&lt;/td&gt;  &lt;td class=&quot;num neg&quot;&gt;-17%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RayTrace&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;10.9&lt;/td&gt;             &lt;td class=&quot;num&quot;&gt;80.1&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;+635%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;EarleyBoyer&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;23.5&lt;/td&gt;             &lt;td class=&quot;num&quot;&gt;74.7&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;+218%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RegExp&lt;/td&gt;       &lt;td class=&quot;num note&quot;&gt;did not complete&lt;/td&gt; &lt;td class=&quot;num&quot;&gt;16.5&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;&amp;ndash;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Splay &lt;/td&gt;       &lt;td class=&quot;num note&quot;&gt;did not complete&lt;/td&gt; &lt;td class=&quot;num note&quot;&gt;did not complete&lt;/td&gt; &lt;td class=&quot;num&quot;&gt;&amp;ndash;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Some tests (Richards, Crypto) see little or no improvement, while others
(DeltaBlue, RayTrace, EarleyBoyer) are dramatically faster.  Just for
comparison, let's run the same benchmark on Safari 4 (JavaScriptCore) and a
Chromium 4 nightly build (V8) on a Mac Pro:&lt;/p&gt;

&lt;table class=&quot;data&quot;&gt;
  &lt;tr&gt;&lt;th&gt;Test&lt;/th&gt;         &lt;th class=&quot;num&quot;&gt;Safari 4&lt;/th&gt; &lt;th class=&quot;num&quot;&gt;Chromium 4&lt;/th&gt; &lt;th class=&quot;num&quot;&gt;Change&lt;/th&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Richards&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;4103&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;4640&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+13%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DeltaBlue&lt;/td&gt;    &lt;td class=&quot;num&quot;&gt;3171&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;4418&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+39%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Crypto&lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;3331&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;3643&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+9%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RayTrace&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;3509&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;6662&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+90%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;EarleyBoyer&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;4737&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;7643&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+61%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RegExp&lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;1268&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;1187&lt;/td&gt;     &lt;td class=&quot;num neg&quot;&gt;-6%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Splay &lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;1198&lt;/td&gt;   &lt;td class=&quot;num&quot;&gt;7290&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;+509%&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;The precise ratios are different, but the same tests that showed the most
improvement from Android 1.6 to 2.0 also show the most improvement from Safari
to Chrome.  Based on this plus the source code snapshot, I'm pretty sure that
Android 2.0 is indeed using V8.&lt;/p&gt;

&lt;p&gt;This is exciting news.  It makes Droid the first shipping product I know that
uses V8 on an ARM processor, although V8 has included an ARM JIT compiler for
some time now.  &lt;em&gt;[Correction: Palm Pre was first; see the comments below.]&lt;/em&gt;
For mobile web developers like me, it means we're one step closer to having
desktop-quality rich web applications on low-power handheld devices.&lt;/p&gt;

&lt;p&gt;Android still lags behind the iPhone in at least one important way for web
developers: CSS animation.  The iPhone (and Safari on the desktop) provides
hardware acceleration for CSS transforms, like this &lt;a href=&quot;http://webkit.org/blog/324/css-animation-2/&quot;&gt;falling leaves demo&lt;/a&gt;.
On Android, CSS animation is done in software, making it &lt;a href=&quot;http://vimeo.com/3697944&quot;&gt;much, much
slower&lt;/a&gt;.  (Even outside the browser, Android's Skia 2D graphics API lacks
hardware acceleration.  OpenGL is the only way to for Android developers to
take advantage of the GPU.)  Accelerated animation would really make it
possible to write interactive web pages that match the smoothness and
responsiveness of native apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final thought:&lt;/strong&gt;  Although the Motorola Droid is still 100 times slower than
Chromium on a Mac Pro, it's already faster at some benchmarks than IE8 or
Firefox 2 on desktop hardware from just a few years ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update (2010-02-09):&lt;/strong&gt; Just for comparison, here are numbers for the
Google/HTC Nexus One with Android 2.1.  The Nexus One is around 2-4 times
faster than the Droid at the V8 benchmark suite.  It even renders the falling
leaves animation at a decent framerate (but still not as smoothly as the
GPU-accelerated iPhone).&lt;/p&gt;

&lt;table class=&quot;data&quot;&gt;
  &lt;tr&gt;&lt;th&gt;Test&lt;/th&gt;         &lt;th class=&quot;num&quot;&gt;Droid (2.0)&lt;/th&gt;            &lt;th class=&quot;num&quot;&gt;Nexus One (2.1)&lt;/th&gt;        &lt;th class=&quot;num&quot;&gt;Change&lt;/th&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Richards&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;15.6&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;52.1&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;+234%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DeltaBlue&lt;/td&gt;    &lt;td class=&quot;num&quot;&gt;12.9&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;60.2&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;+367%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Crypto&lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;10.9&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;31.7&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;+191%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RayTrace&lt;/td&gt;     &lt;td class=&quot;num&quot;&gt;80.1&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;170&lt;/td&gt;                    &lt;td class=&quot;num&quot;&gt;+112%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;EarleyBoyer&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;74.7&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;126&lt;/td&gt;                    &lt;td class=&quot;num&quot;&gt;+69%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;RegExp&lt;/td&gt;       &lt;td class=&quot;num&quot;&gt;16.5&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;27.5&lt;/td&gt;                   &lt;td class=&quot;num&quot;&gt;+67%&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Splay &lt;/td&gt;       &lt;td class=&quot;num note&quot;&gt;did not complete&lt;/td&gt;  &lt;td class=&quot;num note&quot;&gt;did not complete&lt;/td&gt;  &lt;td class=&quot;num&quot;&gt;&amp;ndash;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

</content>
 </entry>
 
 
 
 <entry>
   <title>Compleat: Bash completion for human beings</title>
   <link href="http://limpet.net/mbrubeck/2009/10/30/compleat.html"/>
   <updated>2009-10-30T00:00:00-07:00</updated>
   <id>http://limpet.net/mbrubeck//2009/10/30/compleat</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Compleat&lt;/em&gt; is an easy, declarative way to add smart tab completion for
any command.  It's written in Haskell but requires no programming knowledge.
See the &lt;a href=&quot;http://github.com/mbrubeck/compleat&quot;&gt;GitHub repository&lt;/a&gt; for a quick description, or read on for a
complete explanation.&lt;/p&gt;

&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;I'm one of those programmers who loves to &lt;a href=&quot;http://www.yosefk.com/blog/teeth-marks-at-the-rear-end.html&quot;&gt;carefully tailor my development
environment&lt;/a&gt;.  I do nearly all of my work at the shell or in a text editor,
and I've spent a dozen years learning and customizing them to work more
quickly and easily.&lt;/p&gt;

&lt;p&gt;Most experienced shell users know about programmable completion, which provides
smart tab-completion for supported programs like ssh and git.  You can
also add your own completions for programs that aren't supported&amp;mdash;but in
my experience, most users never bother.&lt;/p&gt;

&lt;p&gt;At Amazon, everyone used Zsh (which has a very powerful but especially baroque
completion system) and shared the completion scripts they wrote for our myriad
internal tools.  Now that I'm in a startup with few other command line
die-hards, I'm on my own when it comes to extending my shell.&lt;/p&gt;

&lt;p&gt;So I read the fine manual and started writing completions.  You can see the
&lt;a href=&quot;http://github.com/mbrubeck/android-completion/blob/master/android&quot;&gt;script I made&lt;/a&gt; for three commands from the Google Android SDK.  It's 200
lines of shell code, and fairly straightforward if you happen to be familiar
with the Bash completion API.  But as I cranked out more and more &lt;code&gt;case&lt;/code&gt;
statements, I felt there must be a better way...&lt;/p&gt;

&lt;h2&gt;The Idea&lt;/h2&gt;

&lt;p&gt;It's not hard to describe the usage of a typical command-line program.
There's even a semi-standard format for it, used in man pages and generated by
libraries like &lt;a href=&quot;http://autogen.sourceforge.net/autoopts.html&quot;&gt;AutoOpt&lt;/a&gt;.  For example, here's the usage for &lt;code&gt;android&lt;/code&gt;, one
of the SDK commands supported by my script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; android [--silent | --verbose]
   ( list [avd|target]
   | create avd ( --target &amp;lt;target&amp;gt; | --name &amp;lt;name&amp;gt; | --skin &amp;lt;name&amp;gt;
                | --path &amp;lt;file&amp;gt; | --sdcard &amp;lt;file&amp;gt; | --force ) ...
   | move avd (--name &amp;lt;avd&amp;gt; | --rename &amp;lt;new&amp;gt; | --path &amp;lt;file&amp;gt;) ...
   | (delete|update) avd --name &amp;lt;avd&amp;gt;
   | create project ( (--package|--name|--activity|--path) &amp;lt;val&amp;gt;
                    | --target &amp;lt;target&amp;gt; ) ...
   | update project ((--name|--path) &amp;lt;val&amp;gt; | --target &amp;lt;target&amp;gt;) ...
   | update adb )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My idea:  What if you could teach the shell to complete a program's arguments
just by writing a usage description like this one?&lt;/p&gt;

&lt;h2&gt;The Solution&lt;/h2&gt;

&lt;p&gt;With &lt;a href=&quot;http://github.com/mbrubeck/compleat&quot;&gt;Compleat&lt;/a&gt;, you can add completion for any command just by writing a
usage description and saving it in a configuration folder.  The ten-line
description of the &lt;code&gt;android&lt;/code&gt; command above generates the same results as my
76-line bash function, and it's &lt;em&gt;so&lt;/em&gt; much easier to write and understand!&lt;/p&gt;

&lt;p&gt;The syntax should be familiar to long-time Unix users.  Optional arguments are
enclosed in square brackets; alternate choices are separated by vertical
pipes.  An ellipsis following an item means it may be repeated, and
parentheses group several items into one.  Words in angle brackets are
parameters for the user to fill in.&lt;/p&gt;

&lt;p&gt;Let's look at some more features of the usage format.  For programs with
complicated arguments, it can be useful to break them down further.  You can
place alternate usages on their own lines separated by semicolons, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;android &amp;lt;opts&amp;gt; list [avd|target];
android &amp;lt;opts&amp;gt; move avd (--name &amp;lt;avd&amp;gt;|--rename &amp;lt;new&amp;gt;|--path &amp;lt;file&amp;gt;)...;
android &amp;lt;opts&amp;gt; (delete|update) avd --name &amp;lt;avd&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...and so on.  Rather than repeat the common options on every line, I used a
parameter named &quot;opts&quot;.  I can define that parameter to be a sub-pattern,
which will be used wherever &lt;code&gt;&amp;lt;opts&amp;gt;&lt;/code&gt; appears:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;opts = [ --silent | --verbose ];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For parameters whose values are not fixed but can be computed by another
program, we use a &lt;code&gt;!&lt;/code&gt; symbol followed by a shell command to generate
completions, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;avd = ! android list avd | grep 'Name:' | cut -f2 -d: ;
target = ! android list target | grep '^id:'| cut -f2 -d' ' ;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Any parameter without a definition will use the shell's built-in completion
rules, which suggest matching filenames by default.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/mbrubeck/compleat&quot;&gt;&lt;strong&gt;The source code is on GitHub.&lt;/strong&gt;&lt;/a&gt;  I've been using it for just a week and
I'm now writing new usage files for myself almost every day.  The README file
has more details about the usage syntax, and instructions for installing the
software.  Give it a try, and please send in any usage files that you want to
share!  (Questions, bug reports, or patches are also welcome.)&lt;/p&gt;

&lt;h2&gt;Future Work&lt;/h2&gt;

&lt;p&gt;For the next release of Compleat, I would like to make installation easier by
providing better packaging and pre-compiled binaries; support &lt;code&gt;zsh&lt;/code&gt; and other
non-bash shells; and write better documentation.&lt;/p&gt;

&lt;p&gt;In the long term, I'm thinking about replacing the usage file interpreter with
a compiler.  The compiler would translate the usage file into shell code, or
perhaps another language like C or Haskell.  This would potentially improve
performance (although speed isn't an issue right now on my development box),
and make it easy for usage files to include logic written in the target
language.  Another idea for the future:  What if option-parsing libraries like
AutoOpt or the Ruby/Perl/Python equivalents generated completion scripts for
every program you wrote?&lt;/p&gt;

&lt;h2&gt;Final Thoughts&lt;/h2&gt;

&lt;p&gt;I realized recently that some things I do are so specialized that my parents
and non-programmer friends will probably never get them.  For example,
Compleat is a program to generate programs to help you&amp;hellip; run programs?
Sigh.  Well, maybe &lt;em&gt;someone&lt;/em&gt; out there will appreciate it.&lt;/p&gt;

&lt;p&gt;Compleat was my weekends/evenings/bus-rides project for the last few weeks (as
you can see in the &lt;a href=&quot;http://github.com/mbrubeck/compleat/graphs/punch_card&quot;&gt;GitHub punch card&lt;/a&gt;), and my most fun side project in
quite a while.  It's the first &quot;real&quot; program I've written in Haskell, though
I've been experimenting with the language for a while.  Now that I'm
comfortable with it, I find that Haskell's particular combination of features
works just right to enable quick exploratory programming, while giving a high
level of confidence in the behavior of the resulting program.  Compleat 1.0 is
just 160 lines of Haskell, excluding comments and imports.  Every module was
completely rewritten at least once as I compared different approaches.  (This
is much less daunting when the code in question is only a couple dozen lines.)
I don't think this particular program would have been quite as easy to
write&amp;mdash;at least for me&amp;mdash;in any of the other platforms I know
(including Ruby, Python, Scheme, and C).&lt;/p&gt;

&lt;p&gt;I had the idea for Compleat more than a year ago, but at the time I did not
know how to implement it easily.  I quickly realized that what I wanted to
write was a specialized parser generator, and a domain-specific language to go
with it.  Unfortunately I never took a compiler-design class in school, and
had forgotten most of what I learned in my programming languages course.  So I
began studying parsing algorithms and language implementation, with Compleat
as my ultimate goal.&lt;/p&gt;

&lt;p&gt;My good friend Josh and his &lt;a href=&quot;http://www.reverberate.org/gazelle/&quot;&gt;Gazelle parser generator&lt;/a&gt; helped inspire me
and point me toward other existing work.  Compleat actually contains three
parsers.  The usage file parser and the input line tokenizer are built on the
excellent &lt;a href=&quot;http://legacy.cs.uu.nl/daan/parsec.html&quot;&gt;Parsec&lt;/a&gt; library.  The usage file is then translated into a
parser that's built with my own simple set of parser combinators, which were
inspired both by Parsec and by the original &lt;a href=&quot;http://www.cs.nott.ac.uk/~gmh/bib.html#monparsing&quot;&gt;Monadic Parser Combinators&lt;/a&gt;
paper by Graham Hutton and Erik Meijer.  The simple evaluator for the usage
DSL applies what I learned from Jonathan Tang's &lt;a href=&quot;http://jonathan.tang.name/files/scheme_in_48/tutorial/overview.html&quot;&gt;Write Yourself a Scheme in
48 Hours&lt;/a&gt;.  And of course &lt;a href=&quot;http://book.realworldhaskell.org/&quot;&gt;Real World Haskell&lt;/a&gt; was an essential
resource for both the nuts and bolts and the design philosophy of Haskell.&lt;/p&gt;

&lt;p&gt;So besides producing a tool that will be useful to me and hopefully others, I
also filled in a gap in my CS education, learned some great new languages and
tools, and kindled an interest in several new (to me) research areas.  It has
also renewed my belief in the importance of &quot;academic&quot; knowledge to real
engineering problems.  I've already come across at least one problem in my
day job that I was able to solve faster by implementing a simple parser than I
would have a year ago by fumbling with regexes.  And I'll be even happier if
this inspires some friends or strangers to take a closer look at Haskell,
Parsec, or any problem they've thought about and didn't know enough to solve.
Yet.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Colophon</title>
   <link href="http://limpet.net/mbrubeck/2009/10/28/colophon.html"/>
   <updated>2009-10-28T00:00:00-07:00</updated>
   <id>http://limpet.net/mbrubeck//2009/10/28/colophon</id>
   <content type="html">&lt;p&gt;This site is powered by &lt;a href=&quot;http://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; and based on styles and markup by &lt;a href=&quot;http://tom.preston-werner.com/&quot;&gt;Tom
Preston Werner&lt;/a&gt;.  Comments are run by &lt;a href=&quot;http://mbrubeck.disqus.com/&quot;&gt;Disqus&lt;/a&gt; and hosting is by
&lt;a href=&quot;http://www.dreamhost.com/r.cgi?31619&quot;&gt;Dreamhost&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before starting this site, I had an &lt;a href=&quot;http://advogato.org/person/mbrubeck/&quot;&gt;Advogato diary&lt;/a&gt; for writing about
software.  I also have a &lt;a href=&quot;http://mbrubeck.livejournal.com/&quot;&gt;personal journal&lt;/a&gt; (mostly interesting to my
friends and family).&lt;/p&gt;
</content>
 </entry>
 
 
 
</feed>
