Top Ten Commands (redux)

A few years ago I posted a list of the top ten commands I use gleaned by parsing the output of history. Here's the origional list ca. 2008:

aaron@athena ~$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
 134 ls
  90 svn
  77 cd
  16 sudo
  15 gvim
  12 rm
  11 script/server
  11 hg
  10 mongrel_rails
   7 slocate

... and here's the new list ca. 2010:

aaron@ares ~$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
 198 hg
  59 paver
  41 ls
  36 ./blogc
  33 cd
  26 python
  19 gvim
  14 fab
  12 rm
  12 ./dist/sassey

And the winner is...

The big change is that Mercurial has completely replaced Subversion as my version control system of choice. Not only that, but I actually use hg more than I used to use svn. Part of this is that hg is better/faster/easier/more useful than svn and part of it is that I've really gotten in the habit of using Mercurial for everything (which you might argue is a consequence of that first thing ;-).

I've started using Paver and Fabric and they are both awesome. I've stopped using Rails, but I was only really using it for school (My current "web framework" of choice is CherryPy, it is also awesome).

./blogc which takes the number four sport, is one of the new tools that I use to work on my blog.

Other than that, I still use gvim, rm, ls, and cd. Shocking!

cat in Sawzall (redux)

After playing with Sawsall a little bit more, I have a slightly better version of cat than the last one I posted:

w: string = input;
emit stdout <- w;

This gets rid of the table and makes the program one whole line shorter :)

New Location, New Tools (redux)

Two years ago I posted that I had moved my blog from Blogger to some django based thing. Recently, I've moved to a different, even more custom, system. In the intervening time, I've written precisely fourteen and one-half blog posts. You may be thinking to yourself: "Surely, that means you spend more time working on your blog's software than actually, y'know, blogging". You would be right, it just turns out that I happen to like it that way.

The new engine is based around the idea of having all of the blog posts stored as reStructuredText documents and then generating all of the indexes/feeds/etc. as a build step producing a bunch of static HTML. This has a couple of neat effects:

  • The entire state of my blog can be stored in version control.
  • I can do all of my editing using my favourite text editor.
  • I can do silly things like running OptiPNG over every single image as a build step.
  • I can say: "My blog software is nginx1."
  • It has the highest YSlow score of anything I have ever worked on.
  • It has a development server (for realz).

Those might sound like the sort of the features that only a programmer could love, well it just so happens that I an one. Sure, this probably only works because (including the post about changing tools) I've only got something like fifteen and two-thirds blog posts, but it all makes more sense if you think of the blog posts I write as cleverly disguised unit tests for whatever blog software I'm working on at the time ;)

[1]It isn't actually. I use Apache just like everybody else. nginx just sounds cooler.

With Statement (Redux)

My previous implementation of the with_statement in ruby had one major flaw: It allowed only a single context manager per with block. While effective, it leads to cluttered code, like the following:

with(open("hello.txt")){|f|
    with(open("bonjour.txt")){|g|
        puts f.read()
        puts g.read()
    }
}

Effective, but it isn't as clear as it could be and introduces more nesting than is really necessary. This coupled with my desire to explore varargs methods and blocks in ruby has lead me to a more robust implementation that can take an arbitrary number of managers as a parameter.

def with(*managers, &block)
    def with_(managers, resources, block)
        if managers.nitems > 0
            begin
                resource = managers.delete_at(0)
                resources << resource.enter()
                with_(managers, resources, block)
            ensure
                resource.exit()
            end
        else
            block.call(*resources)
        end
    end

    with_(managers, [], block)
end

The preceding implementation is more complex than the original. In addition to introducing "star magic"1, it relies on recursive creation of begin-ensure blocks which complicates exception handling; however, this implementation allows for such beautiful usage as:

with(open("hello.txt"), open("bonjour.txt")) {|f, g|
    puts f.read()
    puts g.read()
}

Should a manager's exit method raise an exception, that exception will supersede any exception raised within the block, though it will not interfere with exiting other managers.

An implementation and unittests are available in a Mercurial repository. The implementation can be retrieved as follows:

hg clone http://hg.crimzon.ath.cx/with_statement

Both the implementation and unittests are licensed under the MIT license.

[1]As it is called by pylint.

Lorem Ipsum to Hebrew (redux)

The previous post: Lorem Ipsum to Hebrew gets a little side tracked in the technical details. There's a program to evolve text using mutation-selection cycles and a program to chart the results, but it mostly misses the point.

Questions for Evolutionists asks:

How can mutations (recombining of the genetic code) create any new, improved varieties?
(Recombining English letters will never produce Chinese books.)

This question has two problems. First, it presents a straw man: nobody contends that mutations alone result in the awe inspiring adaptations possessed by the life all around us. The vast majority of mutations are silent-site mutations and have no effect on the phenotype of the resulting creature, because the mutation occurs in a non-coding section and is never expressed. The majority of the rest of mutations are deleterious and give you cancer or Down's syndrome or something equally nasty. Only a tiny fraction of mutations have any beneficial effect on those carrying the mutation.

Mutation alone would never have produced the staggering variety of life that populates the Earth. Mutation combined with selection on the other hand can produce staggering effect on a population. Mutation introduces novel varieties into a population with each generation. While some mutants will be more fit than than their parents most will not be and some will be decidedly less so. The most fit individuals will found the next generation and beneficial mutations will slowly accumulate generation after generation producing the adaptations observed in current populations.

Second, conceptualizing mutation as moving letters around, is a complete underrepresentation of the ways in which our genome's can be mis-copied. There can be deletions, replacements, duplications of single bases or entire sections of DNA. Additionally, it is at the completely wrong level of granularity. Mutation would not occur on the letters themselves but on the bytes representing them. With only 256 bytes to choose from you can represent either Macbeth or the I Ching with ease. Likewise, using only C, G, A and T you can just as easily spell E. Coli and H. Sapiens and you can almost spell Human immunodeficiency virus, but you would be missing the U.

Conclusion

So how can mutation create new and improved variants? When acting alone, mutation would only ever improve an individual through luck. It is after all a random process and would mostly only introduce deleterious changes. When combined with selection on the other hand, together mutation and selection can produce amazing adaptations by allowing beneficial mutations to accumulate over generations.