<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Scott Graham's blog at h4ck3r.net</title>
 <link href="http://h4ck3r.net/atom.xml" rel="self"/>
 <link href="http://h4ck3r.net/"/>
 <updated>2011-09-01T20:04:38-07:00</updated>
 <id>http://h4ck3r.net/</id>
 
 
 <entry>
   <title>Gmail Backup via IMAP using offlineimap</title>
   <link href="/2011/03/13/gmail-backup-imap/"/>
   <updated>2011-03-13T00:00:00-08:00</updated>
   <id>/2011/03/13/gmail-backup-imap</id>
   <content type="html">&lt;p&gt;Every so often I have a minor freakout when I realize the amount of data
that's stored in my Gmail account. The first thing I do is make my
Google account password longer and add more obscure characters. Then, I
feel slightly nervous that it's stored in the US and subject to
&lt;em&gt;who-knows-what&lt;/em&gt; laws.&lt;/p&gt;

&lt;p&gt;Once those feelings pass, I'm mostly concerned that due to &amp;lt;unforseen
circumstance&amp;gt; I might lose access to everything that's in there. It
would be a massive hassle.&lt;/p&gt;

&lt;p&gt;Fortunately, Gmail supports IMAP access to the mail so it should be
relatively straightforward to back up everything. I finally got around
to doing that today. I ended up using &quot;offlineimap&quot; which does what its
name implies.&lt;/p&gt;

&lt;p&gt;First, install offlineimap. On Ubuntu, this is just:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install offlineimap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you know how for other OSs, please feel free to leave a comment.&lt;/p&gt;

&lt;p&gt;Then, I made a configuration file that looks like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ini&quot;&gt;    &lt;span class=&quot;k&quot;&gt;[general]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Gmail&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    maxsyncaccounts = 3&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;[Account Gmail]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;localrepository&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Local&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    remoterepository = Remote&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;[Repository Local]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Maildir&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    localfolders = /backup/USERNAME/mail&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;[Repository Remote]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;IMAP&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    remotehost = imap.gmail.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    remoteuser = USERNAME@gmail.com&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    remotepass = PASSWORD&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    ssl = yes&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    maxconnections = 1&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    realdelete = no&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Of course, you'll need to replace &quot;USERNAME&quot;, &quot;PASSWORD&quot;, and probably
change &quot;/backup/USERNAME/mail&quot; to where you want the backup to live.&lt;/p&gt;

&lt;p&gt;I saved this configuration into &lt;code&gt;/backup/USERNAME/USERNAME.imaprc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, try running it with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;offlineimap -c USERNAME.imaprc -u Noninteractive.Basic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-c&lt;/code&gt; argument points it at our config file rather than ~/.something
and &lt;code&gt;-u&lt;/code&gt; changes the UI to a standard one rather than a heavy colourful
curses default (we're going to use it as a cron job in a second so we
want a log-style).&lt;/p&gt;

&lt;p&gt;If that works, it will probably take a while, but all your mail should
get synced into that folder. You can confirm that everything worked by (e.g.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mutt -f /backup/USERNAME/mail/INBOX
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which will use &quot;mutt&quot; to view the data saved there (you might need to do
&lt;code&gt;sudo apt-get install mutt&lt;/code&gt; for that too). If you look in the &lt;code&gt;mail/&lt;/code&gt;
directory, you should see all your labels, as well as the standard Gmail
ones. And, though the files in the directories have ugly names, each one
corresponds to one mail message stored in text format, so in case of
emergency you could always go grubbing through the files to find
important information.&lt;/p&gt;

&lt;p&gt;Now, if everything looks OK, you'll probably want to schedule this to
run every so often. To accomplish this, I added this script into
&lt;code&gt;/etc/cron.daily&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#/bin/sh
offlineimap -c /backup/USERNAME/USERNAME.imaprc -u Noninteractive.Basic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Don't forget to &lt;code&gt;chmod +x&lt;/code&gt; that script.&lt;/p&gt;

&lt;p&gt;And now I can sleep a little easier. I'd still be a Sad Panda if Gmail
goes away, but I be much less irritated with a backup copy.&lt;/p&gt;

&lt;p&gt;As you might glean from the name of the target directory (&lt;code&gt;/backup&lt;/code&gt;)
this folder is also backed up via rsync. This is probably not necessary
(assuming both Gmail &lt;em&gt;and&lt;/em&gt; your copy don't disappear at the same time)
but it was just as easy for me.&lt;/p&gt;

&lt;p&gt;Another possibility might be to sync Gmail directly into a large Dropbox
folder. While it seems a little silly, it would then be almost
impossible to lose all the copies of your mail that would be scattered
around your various computers.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What can you do in 2k lines of C?</title>
   <link href="/2011/02/02/what-can-you-do-in-2k-of-c/"/>
   <updated>2011-02-02T00:00:00-08:00</updated>
   <id>/2011/02/02/what-can-you-do-in-2k-of-c</id>
   <content type="html">&lt;h3&gt;Plain Old Awesome C&lt;/h3&gt;

&lt;p&gt;A few weeks ago I ran across some of &lt;a href=&quot;http://nothings.org/&quot;&gt;Sean
Barrett&lt;/a&gt;'s awesome C code.&lt;/p&gt;

&lt;p&gt;It started with &lt;code&gt;stb_image.c&lt;/code&gt; because it's just crazy useful and avoids so
much hassle in small demo programs. But that was just the gateway...&lt;/p&gt;

&lt;p&gt;Check out &lt;code&gt;stb_truetype.h&lt;/code&gt; too: TrueType font rendering in one ~1200
line header file. Do you remember how much of a pain in the ass it was
the last time you had to try to integrate FreeType 2? Or &amp;lt;shudder&amp;gt;
FontFusion? If you think about it for a second, you realize that
TrueType rasterization can't be &lt;em&gt;that&lt;/em&gt; hard because printers were doing
it long ago on crappy little embedded processors, but the default is
just to fall back on the big ugly library, and then wrap it and pretend
it's not there. How about instead, just write some good code?&lt;/p&gt;

&lt;p&gt;There's also &lt;code&gt;stb_vorbis.c&lt;/code&gt; (a Vorbis decoder) which I haven't tried
yet, but I fully expect it to Do What I Want, if someday I need it.&lt;/p&gt;

&lt;p&gt;And, on top of that Sean's released these as public domain (partially
thanks to &lt;a href=&quot;http://www.radgametools.com/&quot;&gt;RAD&lt;/a&gt; it seems). Not MIT or BSD,
and certainly not LGPL, GPL, or some other pain in the ass, but straight
up &lt;strong&gt;public domain&lt;/strong&gt;. So much easier when you're embedded in Big Corp,
but even if you're not.&lt;/p&gt;

&lt;p&gt;So, #1, use them. And #2, let's all copy Sean.&lt;/p&gt;

&lt;h3&gt;So, what can &lt;em&gt;you&lt;/em&gt; do in 1-2k?&lt;/h3&gt;

&lt;p&gt;Those libraries are standalone. Zero dependencies other than the C
standard library. There's no build files to screw with. There's no
licenses to get approved by your legal department*. There's no attribution clauses to add
to your &quot;About&quot; box. Just all buttery working-out-of-the-box convenient
awesomeness.&lt;/p&gt;

&lt;p&gt;I got to thinking: What &lt;strong&gt;else&lt;/strong&gt; could be stuffed in 1-2k lines of plain
C?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An JSON / XML / YAML parser?&lt;/li&gt;
&lt;li&gt;Shading?&lt;/li&gt;
&lt;li&gt;A database?&lt;/li&gt;
&lt;li&gt;A GUI library?&lt;/li&gt;
&lt;li&gt;A web server?&lt;/li&gt;
&lt;li&gt;Rendering?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Since I've been language-obsessed the last few years, my first 1-2k LOC
project is a &lt;a href=&quot;http://code.google.com/p/twok/source/browse/&quot;&gt;programming language, appropriately named
&quot;twok&quot;&lt;/a&gt;. Calling it
something that sounds like poop dropping into a toilet probably means
that no one will want to use it, but that's probably for the best
anyway; there's lots of languages out there.&lt;/p&gt;

&lt;p&gt;The question is, how much functionality can you get into 2k lines of
code? So far, twok's features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python-style syntax&lt;/li&gt;
&lt;li&gt;The &quot;basics&quot;: arithmetic, bit ops, logic ops, functions, &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;Native compilation to x64 (and supporting both Windows and SysV Mac/Linux ABIs) so you can call back and forth with C code&lt;/li&gt;
&lt;li&gt;List syntax/manipulation&lt;/li&gt;
&lt;li&gt;Simple zone-based GC&lt;/li&gt;
&lt;li&gt;Varargs functions&lt;/li&gt;
&lt;li&gt;Basic structs&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And, it's just a hair over &lt;strong&gt;1k LOC&lt;/strong&gt;, and of course, all in one
easy-to-use header. My plan for the second half of the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some sort of macros&lt;/li&gt;
&lt;li&gt;More standard library functions&lt;/li&gt;
&lt;li&gt;List comprehension syntax&lt;/li&gt;
&lt;li&gt;Integration with the new GDB &lt;a href=&quot;http://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html#JIT-Interface&quot;&gt;debugging-support-for-JITted-languages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A backend for ARM, and maybe an interpreter backend for consoles&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;... Or other fun suggestions. I'm not sure if all of that will fit in
2k, but I think it should be close.&lt;/p&gt;

&lt;p&gt;Certainly this is will not be the next C# or Ruby. And it's not as
practical as image loading, font rendering, or audio decoding. But, I
think it's interesting how much a hard constraint on size and a clear
goal helps focus and at the same time find a way to stuff in the
functionality you want.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So, what awesome library could you write in 1-2k lines of C?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's fun!&lt;/p&gt;

&lt;p&gt;And release it as public domain.&lt;/p&gt;

&lt;p&gt;Programmers everywhere will love you.&lt;/p&gt;

&lt;p&gt;&lt;sub&gt;*: yeah, I know that's probably still not true, unfortunately.&lt;/sub&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Data Oriented C</title>
   <link href="/2011/01/07/data-oriented-c/"/>
   <updated>2011-01-07T00:00:00-08:00</updated>
   <id>/2011/01/07/data-oriented-c</id>
   <content type="html">&lt;p&gt;There's been a lot of noise (and some light) up in The Twitters about Data
Oriented Design. &lt;a href=&quot;http://solid-angle.blogspot.com/2010/02/musings-on-data-oriented-design.html&quot;&gt;Noel
Llopis&lt;/a&gt;,
&lt;a href=&quot;http://solid-angle.blogspot.com/2010/02/musings-on-data-oriented-design.html&quot;&gt;Steve
Anichini&lt;/a&gt;,
Mike Acton
&lt;a href=&quot;http://www.insomniacgames.com/tech/articles/0809/files/concurrency_rabit_hole.pdf&quot;&gt;e.g.&lt;/a&gt;,
&lt;a href=&quot;http://www.google.com/buzz/mrengstad/9L1HaA3NuZS/Recently-the-debate-on-OOD-object-oriented-design&quot;&gt;P&amp;aring;l-Kristian
Engstad&lt;/a&gt;,
&lt;a href=&quot;https://docs.google.com/present/view?id=0AYqySQy4JUK1ZGNzNnZmNWpfMzJkaG5yM3pjZA&amp;amp;hl=en&quot;&gt;Niklas
Frykholm&lt;/a&gt;.
&lt;a href=&quot;http://twitter.com/#!/christerericson&quot;&gt;Christer Ericson&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/#!/bionicbeagle&quot;&gt;Stefan
Boberg&lt;/a&gt;, and many others have been
having at it.&lt;/p&gt;

&lt;p&gt;The points under discussion are well described in those, so I'll defer
to them. Read P&amp;aring;l-Kristian Engstad's first if you want to get up to speed
quickly.&lt;/p&gt;

&lt;p&gt;Most often, I find myself hitting one of the extremes. I either want to
use something very high-level and script-y (Python, Ruby), or something
very low-level (Assembler, C, ???).&lt;/p&gt;

&lt;p&gt;The benefit of the high-level of course, is that you might have the
functionality magically accomplished for you by a library or language
feature. If you're forced to parse some XML, then generate an image, and
POST the result to a server, well, you're probably going to get it done
orders of magnitude sooner in a scripting language.&lt;/p&gt;

&lt;p&gt;For in-game where you're working on code that's run every frame though,
it's likely that you're going to need to carefully design the layout
of your data.&lt;/p&gt;

&lt;p&gt;In C this means focusing on getting all the data to accomplish a
particular task together into a (preferably cache-line-sized) chunk, and
grouping a bunch of those together. In C++ it naturally means the
same thing, but it also means staying true to your inner C programmer
and not getting lured by the Sirens' Song of &lt;code&gt;virtual&lt;/code&gt;s up the wazoo.&lt;/p&gt;

&lt;p&gt;My thinking is that it would be useful to make a &lt;strong&gt;small extension&lt;/strong&gt; to
C (or C++?) that supports this method of thinking about problems. Call
it &lt;strong&gt;Data Oriented C&lt;/strong&gt;, a strict superset of C. The goals would be to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;encourage a more stream-centric programming model&lt;/li&gt;
&lt;li&gt;encourage grouping the data for a problem into little cache-sized
packets&lt;/li&gt;
&lt;li&gt;auto-instrument to make performance and data flow easily understood.&lt;/li&gt;
&lt;li&gt;support distribution of work across processors&lt;/li&gt;
&lt;li&gt;not be too hostile to IDEs, editors, and debuggers&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;What other goals do you have?&lt;/p&gt;

&lt;h3&gt;A &amp;rarr; A&amp;prime;&lt;/h3&gt;

&lt;p&gt;The general idea (as espoused by Mike Acton) is that rather than
thinking of your program as manipulating a bunch of objects, think of it
as transforming data from one form to another, i.e. from A to A&amp;prime;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I like to think of this as the Unix pipes model&lt;/strong&gt;, e.g.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cat data | sort | uniq
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is easy to write, easy to test, and easy to understand.&lt;/p&gt;

&lt;p&gt;Perhaps we can encourage that by supporting it more directly in the
language (&lt;em&gt;off-the-cuff arbitrary syntax&lt;/em&gt;):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ToWorld&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mat44&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mat44&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;(where &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;output&lt;/code&gt;, and &lt;code&gt;operation&lt;/code&gt; are new keywords.)&lt;/p&gt;

&lt;p&gt;Of course, we could extend the syntax or use helper libraries to go wide
in the body of the &lt;code&gt;operation&lt;/code&gt;. We could also deviate farther from C and
add more specialized &lt;code&gt;operation&lt;/code&gt; styles eventually. e.g. a &lt;code&gt;map&lt;/code&gt; could
elide the &lt;code&gt;for&lt;/code&gt; loop, and remove the array subscripting replacing
&lt;code&gt;input[i]&lt;/code&gt; with just &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;output[i]&lt;/code&gt; with &lt;code&gt;out&lt;/code&gt;. That sort of sugar
probably doesn't belong in an early version though.&lt;/p&gt;

&lt;h3&gt;Piping&lt;/h3&gt;

&lt;p&gt;It might also be useful helpful to support a high-level syntax for
composition &amp;agrave; la Unix pipes. Plain &lt;code&gt;|&lt;/code&gt; is already taken, so
perhaps following F# for a &lt;code&gt;|&amp;gt;&lt;/code&gt; operator:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;SceneNodeCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nodes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ToWorld&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cull&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrepareForRender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;where &lt;code&gt;ToWorld&lt;/code&gt;, &lt;code&gt;Cull&lt;/code&gt;, and &lt;code&gt;PrepareForRender&lt;/code&gt; are &lt;code&gt;transform&lt;/code&gt;s as
defined above.&lt;/p&gt;

&lt;p&gt;Is this necessary? Or do people generally want to hardcode the
transformation compositions, or set them up at runtime based on
configuration data?&lt;/p&gt;

&lt;p&gt;Having the composition hardcoded allows for some improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It would allow intelligent overlapping of input and outputs to either
reduce or disallow copies.&lt;/li&gt;
&lt;li&gt;It would also be a good place to break into packets for DMA to
processors that don't share memory.&lt;/li&gt;
&lt;li&gt;It could also make for an nice place to add instrumentation for
gathering timing data.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Implementation&lt;/h3&gt;

&lt;p&gt;Doing Data Oriented C as an extension of a plain C parser wouldn't too
hard, it could probably just be written by hand.&lt;/p&gt;

&lt;p&gt;If it's to be an extension of C++ (probably more palatable for most
people), it doesn't seem like it would be too hard to extend
&lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; to do a source-to-source transformation
from Data Oriented C(++) to plain C(++). Realistically, that's probably
a better option for plain C too.&lt;/p&gt;

&lt;h3&gt;Thoughts&lt;/h3&gt;

&lt;p&gt;Data Oriented C doesn't fundamentally do anything magical that you
couldn't do in C (naturally). It's all about making the &lt;a href=&quot;http://nihrecord.od.nih.gov/newsletters/2009/01_23_2009/story3.htm&quot;&gt;&lt;em&gt;default&lt;/em&gt;
decision be the correct
one&lt;/a&gt;.
It could also make it easier to help out the C compiler, for example by
correctly adding &lt;code&gt;__restrict&lt;/code&gt; annotations when appropriate.&lt;/p&gt;

&lt;p&gt;It seems like this would only be useful if it was designed by and used
across a few studios. So, what do you think? What's the feature you'd
like to see removed or added? Is the whole thing even necessary? How
would you change it? &lt;a href=&quot;http://twitter.com/#!/sgraham_guid&quot;&gt;Twitter&lt;/a&gt;,
&lt;a href=&quot;mailto:scott.doc@h4ck3r.net&quot;&gt;email&lt;/a&gt;, or comment below.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Improve your App Launch in 4 hours</title>
   <link href="/2010/11/28/improve-your-app-launch-in-4-hours/"/>
   <updated>2010-11-28T00:00:00-08:00</updated>
   <id>/2010/11/28/improve-your-app-launch-in-4-hours</id>
   <content type="html">&lt;p&gt;Picture a customer looking to solve her particular business problem.
Very occasionally, she might be looking to solve a problem in 5 minutes
or less, and simply be willing to choose the first thing that sort of
works that she runs across.&lt;/p&gt;

&lt;p&gt;More likely though, she wants the &lt;strong&gt;best solution for her&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From experience, she knows that choosing the first half-assed solution
isn't going make for a &lt;strong&gt;long-term victory&lt;/strong&gt;. Inevitably, it's going to
mean more hassle later on, because something won't work, or there will
be a migration cost, or the company will just be a pain to deal with.&lt;/p&gt;

&lt;h3&gt;Evaluation&lt;/h3&gt;

&lt;p&gt;When a customer is performing evaluation of specific solutions, they
can't possibly have complete information. They're not going to have used
all the software for extended periods. Reviews and recommendations are
one method of pruning the search, but a review describes how well the
product fits the reviewer, not how well it will fit another specific
person.&lt;/p&gt;

&lt;h3&gt;What does this mean to you?&lt;/h3&gt;

&lt;p&gt;Lacking complete information, a customer is looking for &lt;em&gt;signalling&lt;/em&gt;
that tells them that &lt;strong&gt;everything's going to be OK&lt;/strong&gt; if they go with
you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's going solve their problem.&lt;/li&gt;
&lt;li&gt;They're not going to get hassled later.&lt;/li&gt;
&lt;li&gt;They're going to get good value for their money.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If you're reading this, you're clearly someone who &lt;strong&gt;cares&lt;/strong&gt; about your
business, your application, and your customers. You are &lt;em&gt;hungry&lt;/em&gt; and
&lt;em&gt;eager&lt;/em&gt;. You are the polar &lt;em&gt;opposite&lt;/em&gt; of the other half-assed company
that out-sourced development, design, and UX. You are the &lt;em&gt;opposite&lt;/em&gt; of
the huge faceless corporation that can't really be bothered with smaller
customers, or solving their &quot;trivial&quot; problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;That you care deeply is what you must demonstrate to your customers.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Focusing resources&lt;/h3&gt;

&lt;p&gt;Of course, you're exhausted already. You're trying to launch here!
You're trying to cram all your launch features in, you're scrambling to
fix the blasted thing in IE. How are you going find time to actively
&lt;strong&gt;demonstrate that you care&lt;/strong&gt; while you're too busy &lt;strong&gt;actually caring&lt;/strong&gt;?&lt;/p&gt;

&lt;h3&gt;Slice of Caring&lt;/h3&gt;

&lt;p&gt;The practical solution to this problem is what I awkwardly call a &quot;Slice
of Caring&quot;.&lt;/p&gt;

&lt;p&gt;Instead of trying to show off that you care in every aspect across your
whole business, you choose one particular slice to use as a
demonstration of your commitment.&lt;/p&gt;

&lt;p&gt;Of course, you &lt;strong&gt;do&lt;/strong&gt; actually care about the entire business, but the
effort involved in demonstrating this is huge, so pick something more
manageable.&lt;/p&gt;

&lt;p&gt;In particular, you probably want to &lt;strong&gt;pick something flashy&lt;/strong&gt; because
that's where users will look first. Flashy depends on your application
and problem domain. It might mean supporting the newest gadget, or it
might mean integrating with Microsoft Outlook, or it might mean
streamlining their Basecamp workflow, or it might be some other
customization for a vertical-within-a-vertical-within-a-niche that a
specific type of lawyer will love.&lt;/p&gt;

&lt;p&gt;I don't know what it will be for you, but you can definitely find
something.&lt;/p&gt;

&lt;p&gt;In my case, I was launching DropPic, an application for &lt;a href=&quot;http://droppic.com/&quot;&gt;designers to
create galleries of comps and mockups&lt;/a&gt;. A few
designers had mentioned that their clients were iPad-obsessed, and would
really like to review designs on the iPad.&lt;/p&gt;

&lt;p&gt;So, I added a review mode, customized for the iPad. You can try it &lt;a href=&quot;http://droppic.com/reviewer/6671513f116a4f0ba8c9db5702a6b229&quot;&gt;here
if you're on an
iPad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(On a WebKit-based desktop browser, you can add &lt;code&gt;?forcemob=1&lt;/code&gt; to the
 preview page to see it. It doesn't work properly, but you can get the
 general idea.)&lt;/p&gt;

&lt;p&gt;My customers are &lt;strong&gt;thrilled&lt;/strong&gt; because they know their clients will love
it, and what they want is &lt;strong&gt;happy, paying clients&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This took me 4 hours&lt;/strong&gt;, from deciding to do it, to figuring out that
Sencha Touch was probably the fastest way to get it done, to
implementation. It involved no changes to the backend, and is only about
200 lines of code. This is the sort of flashy feature you're looking
for.&lt;/p&gt;

&lt;p&gt;It's important that you &lt;em&gt;not dig yourself a maintenance hole&lt;/em&gt;. Pick
something that's both a slice to show you care, and also a standalone
column of functionality that isn't going to break every time you change
your application.&lt;/p&gt;

&lt;p&gt;In my case, I'm using the same API for communication, so it's strictly a
different UI. If you were, for example, pulling contacts from Outlook,
you'd want to make sure that the &quot;slice&quot; was tool that talked
to Outlook, got data, and stuffed it through your regular
contact-importing-procedure, whatever that might be. Don't
create exceptions and special cases for extra features,
because that'll definitely come back to haunt you.&lt;/p&gt;

&lt;h3&gt;Do it now&lt;/h3&gt;

&lt;p&gt;This is of key importance.&lt;/p&gt;

&lt;p&gt;Demonstrating that you care is difficult. Caring is one thing, but
before they've used your great product, or experienced your outstanding
customer support, prospective customers won't really know if you care.
They therefore won't know whether they're going to be happy with your
product.&lt;/p&gt;

&lt;p&gt;You must expend &lt;strong&gt;additional&lt;/strong&gt; effort to show them that you care about the
big picture, the little details, and everything in between.&lt;/p&gt;

&lt;p&gt;Without the extra effort, they're never going to experience the
excellence you have to offer.&lt;/p&gt;

&lt;p&gt;But you can find something that will only take you 4 hours, be suitable
for signalling, and will &lt;a href=&quot;http://news.ycombinator.com/item?id=1773398&quot;&gt;improve your
launch&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hackage for Android and Vonage voicemail .wav's</title>
   <link href="/2010/09/08/hackage-for-android-vonage-voicemail-wav/"/>
   <updated>2010-09-08T00:00:00-07:00</updated>
   <id>/2010/09/08/hackage-for-android-vonage-voicemail-wav</id>
   <content type="html">&lt;p&gt;Froyo (Android 2.2)
&lt;a href=&quot;http://code.google.com/p/android/issues/detail?id=8730&quot;&gt;broke&lt;/a&gt; the
playing of Vonage's attached voicemails. I think it's because
they're not really .wav's or something, but whatever the reason,
it's a total pain in the ass.&lt;/p&gt;

&lt;p&gt;Presumably it'll be fixed in Gingerbread, but it was driving me crazy in
the meantime.&lt;/p&gt;

&lt;p&gt;I hacked together some of the worst code ever. I honestly felt like I
was programming like an AI would: Google for something, paste it, run
it, &lt;em&gt;then&lt;/em&gt; read it to see why it didn't work, and repeat.&lt;/p&gt;

&lt;p&gt;Anyway, it took me almost an hour, so here it is case it helps someone else.&lt;/p&gt;

&lt;p&gt;Put it in &lt;a href=&quot;/images/wavconv.py&quot;&gt;&lt;code&gt;wavconv.py&lt;/code&gt;&lt;/a&gt; (or whatever) and run it as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python wavconv.py your_user_id@gmail.com your_gmail_password
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses &lt;code&gt;sox&lt;/code&gt; to convert the wav's to .ogg which seem to play OK on my
Nexus One. To install sox on Ubuntu, just do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install sox
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please feel free to leave a comment if you know how to do it for another
platform.&lt;/p&gt;

&lt;p&gt;It sits in a loop and checks for messages every 2 minutes, converting
them if it sees a new one. So, you'll probably want to run it on a
server in a &lt;code&gt;screen&lt;/code&gt; session. Or maybe it'd be better in cron and delete
the loop/sleep.&lt;/p&gt;

&lt;p&gt;Contents of the above link, below.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;getpass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;imaplib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;smtplib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.mime.multipart&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEMultipart&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.MIMEBase&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEBase&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.mime.text&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEText&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.mime.message&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEMessage&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Encoders&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;usage: wavconv.py user@gmail.com your_password&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imaplib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMAP4_SSL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;imap.gmail.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;INBOX&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;(SUBJECT &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;new voicemail&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;emailid&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emailid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;(RFC822)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;email_body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message_from_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email_body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_content_maintype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;multipart&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

        &lt;span class=&quot;c&quot;&gt;#print &amp;quot;[&amp;quot;+mail[&amp;quot;From&amp;quot;]+&amp;quot;]: &amp;quot; + mail[&amp;quot;Subject&amp;quot;]&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;walk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_content_maintype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;multipart&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Content-Transfer-Encoding&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;base64&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Date&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;c&quot;&gt;# hacky non-dupe!&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;From&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sox &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; conv.ogg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;# build a response and send it (ugh!)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEMultipart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Subject&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;From&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Subject&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;From&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;To&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;attach&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEBase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;audio&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;ogg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;conv.ogg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Encoders&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode_base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Content-Disposition&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;attachment; filename=&amp;quot;conv.ogg&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;smtplib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SMTP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;smtp.gmail.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;587&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ehlo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;starttls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ehlo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendmail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;From&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;To&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;converted&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>Skulpt Parsing Revisited</title>
   <link href="/2010/08/19/skulpt-parsing-revisited/"/>
   <updated>2010-08-19T00:00:00-07:00</updated>
   <id>/2010/08/19/skulpt-parsing-revisited</id>
   <content type="html">&lt;p&gt;Over and over, I &quot;rediscover&quot; that the easiest and most reliable way to
do something is to have an exact description of what needs to be done.&lt;/p&gt;

&lt;p&gt;That sounds like a tautology, but when applied to code it can be very
powerful.&lt;/p&gt;

&lt;p&gt;My latest reinforcement and example of this idea was in my renewed
attempt to get &lt;a href=&quot;http://www.skulpt.org/&quot;&gt;Skulpt&lt;/a&gt; back on the rails to
something that I could maintain and extend more easily.&lt;/p&gt;

&lt;p&gt;The first time around I was a bit overwhelmed: it turns out that
implementing a full version of Python is quite a large undertaking (who
knew! &lt;code&gt;&amp;lt;ahem&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;But, the thing is, there's plenty of help available. There's of course
the source code to CPython. I have referred to that quite frequently,
because when it comes down to it, that's unfortunately the only
&quot;spec&quot; for Python.&lt;/p&gt;

&lt;p&gt;However, it doesn't turn out to be the most useful thing. The most
useful thing, by far, &lt;strong&gt;&lt;em&gt;is the ability to generate tons of test data
that's known-good&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The first time around on trying to write a compiler, I had done the
obvious thing of passing python code to CPython and also to my compiler,
and then making sure that running them both resulted in identical
output.&lt;/p&gt;

&lt;p&gt;However, the crucial part that I didn't do was to mirror CPython at
&lt;strong&gt;&lt;em&gt;other levels&lt;/em&gt;&lt;/strong&gt; of implementation.&lt;/p&gt;

&lt;p&gt;As one example, there's any number of ways you could choose to implement
scoping and binding of names in a programming language. By only
comparing the run output between CPython and Skulpt I was effectively
reverse engineering a lot of that knowledge. Of course, for the common
cases, everyone knows how variables are bound, shadowed, closed over,
deleted, etc. But it's the obscure cases that need to be correct so
that everything is rock-solid, and that's where you never feel sure
that you've considered all cases in tests.&lt;/p&gt;

&lt;p&gt;So, the &lt;strong&gt;&lt;em&gt;magic step&lt;/em&gt;&lt;/strong&gt; this time around: I made sure there was two
more levels where I could dump internal state from CPython and make sure
that it matched Skulpt's exactly. Both the AST nodes (using the &lt;a href=&quot;http://docs.python.org/library/ast.html#ast.dump&quot;&gt;&lt;code&gt;ast&lt;/code&gt;
module&lt;/a&gt;) and
the symbol table (using the &lt;a href=&quot;http://docs.python.org/library/symtable.html&quot;&gt;&lt;code&gt;symtable&lt;/code&gt;
module&lt;/a&gt;) now match
1:1 between Skulpt and CPython. This includes many little details that
are important but easily overlooked: line numbers and column offsets
being identical in the AST for error messages, all variables being
tagged as &lt;code&gt;free&lt;/code&gt; or &lt;code&gt;cell&lt;/code&gt; identically, and so on.&lt;/p&gt;

&lt;p&gt;This was huge for my confidence in correctness. I now have the ability
to generate as much test data as I want for the AST and symbol table. I
could, for example feed all of &lt;code&gt;Python/Lib/*.py&lt;/code&gt; to both Skulpt and
CPython and compare a pretty-print of the ASTs and symbol tables.&lt;/p&gt;

&lt;p&gt;Or, in other words, &lt;em&gt;I have an exact description of what needs to be
done&lt;/em&gt; in test-data form. How hard can it be at that point?&lt;/p&gt;

&lt;p&gt;The AST and symbol table are two big chunks of the implementation of the
compiler. With confidence that they contain a correct version of all the
information required, I now have a solid foundation to build the rest.&lt;/p&gt;

&lt;p&gt;The &quot;rest&quot; is compilation of the AST to &lt;code&gt;.js&lt;/code&gt;, runtime support, and the
object model. More on their progress next time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Opcode Design for a Lisp processor</title>
   <link href="/2010/06/14/some-opcode-design/"/>
   <updated>2010-06-14T00:00:00-07:00</updated>
   <id>/2010/06/14/some-opcode-design</id>
   <content type="html">&lt;p&gt;I've been thinking about trying to design and build a TTL-based
processor for the last few weeks, and specifically trying to make it
something that supports Lisp as its standard language.&lt;/p&gt;

&lt;p&gt;Going all the way down to the level of electricity definitely opens up
the design options, perhaps way too far! It's very difficult to decide
where best to solve a problem when you're able to change everything from
word size and available hardware, all the way up through to compiler
implementation.&lt;/p&gt;

&lt;p&gt;I've gone through about 10 each of completely different architectures,
instruction set styles, opcode encodings, word sizes, and so on.&lt;/p&gt;

&lt;p&gt;I started with something based on Sussman and Steele's SIMPLE, then
veered off into a SECD-style machine, then explored things similar to
the PDP-11 instruction set.&lt;/p&gt;

&lt;p&gt;Many of my attempted designs were pretty &quot;top-down&quot; in the sense that I
started writing assemblers and simulators for them, and got carried away
designing fancy instruction sets that were either too non-orthogonal, or
just simply way too complicated for me ever to have a chance of
implementing them in basic TTL logic. Others were just plain silly or
broken.&lt;/p&gt;

&lt;p&gt;Here's a random brain dump of what I'm thinking now. Given my current rate of
starting over, it's not really likely that this one will be the one I
actually build, but this is where I'm at now.&lt;/p&gt;

&lt;p&gt;RAM is 32k, divided into 2 half spaces. Pointers are 13 bits long and
address 16bit words, making for 8k addressable words. 16 registers are
mapped into the low 16 words.&lt;/p&gt;

&lt;p&gt;Out-of-memory is sort of like a &quot;fault&quot; and jumps to a system provided
(or user-written &lt;code&gt;:)&lt;/code&gt;) GC routine.&lt;/p&gt;

&lt;p&gt;Embedded description of opcodes and encoding (or
&lt;a href=&quot;http://spreadsheets.google.com/pub?key=0AreKWASMXkZTdGFrSFRBSDNPNUNwRXc4WWlsRjlGVVE&amp;amp;single=true&amp;amp;gid=0&amp;amp;output=html&quot;&gt;external&lt;/a&gt;
if that sucks).&lt;/p&gt;

&lt;iframe width='700' height='400' frameborder='0' src='http://spreadsheets.google.com/pub?key=0AreKWASMXkZTdGFrSFRBSDNPNUNwRXc4WWlsRjlGVVE&amp;single=true&amp;gid=0&amp;output=html&amp;widget=true'&gt;&lt;/iframe&gt;


&lt;p&gt;It's pretty PDP-11-y, but simpler, and the modified to my liking. &lt;code&gt;cons&lt;/code&gt;
is a basic instruction, and &lt;code&gt;car&lt;/code&gt;, &lt;code&gt;cdr&lt;/code&gt;, &lt;code&gt;rplaca&lt;/code&gt;, &lt;code&gt;rplacd&lt;/code&gt; have one
instruction implementations too.&lt;/p&gt;

&lt;p&gt;I never got around to properly writing up older designs, but some of the
code is &lt;a href=&quot;http://code.google.com/p/lpu/source/browse/&quot;&gt;here along with some mumbly text files about design for various
versions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main.lisp&lt;/code&gt; simulates one design (based on SIMPLE), which uses Lisp tree
structures as the basis for evaluation, as opposed to the usual linear
stream of instructions. Type bits in the pointers are things like &lt;code&gt;if&lt;/code&gt;,
&lt;code&gt;lambda&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;opcodes.lisp&lt;/code&gt; &amp;amp; &lt;code&gt;as.py&lt;/code&gt; simulate a different custom design. It's sort of
an accumulator design, but most operations can be accumulated to A &lt;em&gt;or&lt;/em&gt;
D, and then in some cases, A and D are treated as one register for
simple cons-cell handling.&lt;/p&gt;

&lt;p&gt;I haven't written a simulator for the version described above in the
spreadsheet, but that's next, assuming it survives the next round of
pondering.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The hardware side of a Lisp Processing Unit</title>
   <link href="/2010/05/31/the-hardware-side-of-a-lisp-processing-unit/"/>
   <updated>2010-05-31T00:00:00-07:00</updated>
   <id>/2010/05/31/the-hardware-side-of-a-lisp-processing-unit</id>
   <content type="html">&lt;p&gt;A couple months ago, I &lt;a href=&quot;/2010/03/02/a-new-old-processor/&quot;&gt;was thinking about trying to build a processor
based on Lisp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I got some time and motivation again to work on this (who knows where it
comes from some times). I think perhaps it was finding the
&lt;a href=&quot;http://web.cecs.pdx.edu/~harry/Relay/&quot;&gt;excellently-crazy Relay Computer that Harry Porter
built&lt;/a&gt;. Bill Buzbee made an
&lt;a href=&quot;http://www.homebrewcpu.com/&quot;&gt;amazing and more functional computer&lt;/a&gt; out
of mere discrete logic TTL chips, also very impressive. (And I expect
that's the first time it's ever been described as a &lt;em&gt;more&lt;/em&gt; functional
computer.)&lt;/p&gt;

&lt;p&gt;A relay is a very big clunky version of a transistor. When power is
supplied to a control line, it activates an electromagnet, which causes
a switch on a spring to be shoved from touching one output line to
touching the other. In this way, you can cause incoming electricity go
one way or the other based on the switch.&lt;/p&gt;

&lt;p&gt;But that's it. That's all they do.&lt;/p&gt;

&lt;p&gt;Building a computer out of these large &lt;em&gt;things&lt;/em&gt; captures the
magic of creating a computation machine out of thin air. Everyone can
understand the description of a relay, and has probably played with
magnets and electromagnets. When you string a whole lot of these
switches together and attach them in a specific way, you suddenly get a
computer? How? &lt;em&gt;&amp;lt;insert-Zen-moment-here&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Somehow in the TTL version (which of course is really very similar,
except faster) it feels like the computation might be &quot;hiding&quot; in those
chips somewhere. Of course they're really just switches too, and
they switch much more efficiently.&lt;/p&gt;

&lt;p&gt;Maybe it's just some silly human thing to enjoy the clicking noises that
make it feel like &quot;It's really doing something in there.&quot;&lt;/p&gt;

&lt;h4&gt;Onwards&lt;/h4&gt;

&lt;p&gt;I currently know roughly nil about electricity, but was inspired enough
to think it might help things if I tried to burn my fingertips with a
soldering iron: I ordered &lt;a href=&quot;http://www.makershed.com/ProductDetails.asp?ProductCode=9780596153748&quot;&gt;Make:
Electronics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Experienced electronics dudes will probably sneer at the fact that I
also ordered &lt;a href=&quot;http://www.makershed.com/ProductDetails.asp?ProductCode=MECP1&quot;&gt;their
kit&lt;/a&gt; that
includes all the bits needed for the first 12 experiments. I'm sure it's
overpriced for the raw parts I'm getting, but hopefully will flatten the
learning and frustration curve, not to mention me wasting money buying
all kinds of &lt;em&gt;not-quite-right&lt;/em&gt; bits.&lt;/p&gt;

&lt;p&gt;How long can it possibly take before I'm prepped to make a relay
computer, right? &lt;code&gt;:)&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Disable STYLE-WARNING on sbcl</title>
   <link href="/2010/05/30/disable-style-warnings-on-sbcl/"/>
   <updated>2010-05-30T00:00:00-07:00</updated>
   <id>/2010/05/30/disable-style-warnings-on-sbcl</id>
   <content type="html">&lt;p&gt;When sbcl wants to tell you that it's unable to generate the best code,
or at least unambiguously compile the code you give it, it emits a
STYLE-WARNING. Generally, the warnings are things like functions that
haven't been defined, and so are things you do want to know about.&lt;/p&gt;

&lt;p&gt;But, when you're working interactively, it spits out a warning that I
find irritating, telling you that you're redefining a function. Well,
duh, I know.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;STYLE-WARNING: redefining HOST-GC in DEFUN
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I'm sure there's some sensible reason for this, but I'd still rather not
see it.&lt;/p&gt;

&lt;p&gt;Also, in using someone else's code (perhaps written on a different
Common Lisp) there's often a spew of STYLE-WARNINGs too. For example,
I'm using
&lt;a href=&quot;http://www.cs.northwestern.edu/academics/courses/325/readings/lisp-unit.html&quot;&gt;lisp-unit&lt;/a&gt;,
a simple testing thingy. It works nicely enough, but sbcl spits out lots
of warnings as it loads it.&lt;/p&gt;

&lt;p&gt;I had to hunt around for a while to find the way to silence these, as it
wasn't obvious from the sbcl docs, but this is the way to nuke the
warning while &lt;code&gt;load&lt;/code&gt;ing a particular file. For example, with lisp-unit:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cl&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;declaim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#+&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sbcl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sb-ext:muffle-conditions&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;style-warning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;lisp-unit.lisp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;declaim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#+&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sbcl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sb-ext:unmuffle-conditions&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;style-warning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;#+sbcl&lt;/code&gt; makes it conditional for sbcl. That bit of code would fail
on other CLs because of the &lt;code&gt;sb-ext&lt;/code&gt;. I occasionally run on ClozureCL
too, but it doesn't cause warnings in the same way, and I haven't had a
need to silence warnings there.&lt;/p&gt;

&lt;p&gt;You may or may not want to wrap that &lt;code&gt;declaim&lt;/code&gt; around your interactive
bits, weighing that you might miss more important warnings of course.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fix Ubuntu 10.04 Lucid minimize/maximize/close button position</title>
   <link href="/2010/05/29/fix-ubuntu-buttons/"/>
   <updated>2010-05-29T00:00:00-07:00</updated>
   <id>/2010/05/29/fix-ubuntu-buttons</id>
   <content type="html">&lt;p&gt;I &lt;a href=&quot;http://twitter.com/sgraham_guid&quot;&gt;tweeted&lt;/a&gt; this on first install, but
that's like throwing it into wind if you ever want to remember it (i.e.
when I install on a new PC).&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;leftist&lt;/strong&gt; conspiracy must be fought people! Here's the one liner
you're looking for:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gconftool -s /apps/metacity/general/button_layout -t string &quot;menu:minimize,maximize,close&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is all. Fight The Power! Represent The People! Other Nonsensical
Slogan!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Copying syntax highlighted code from Vim</title>
   <link href="/2010/05/27/vim-to-clipboard-highlighted-code/"/>
   <updated>2010-05-27T00:00:00-07:00</updated>
   <id>/2010/05/27/vim-to-clipboard-highlighted-code</id>
   <content type="html">&lt;p&gt;Occasionally, I need to email code to a co-worker, and in general,
Outlook seems to enjoy destroying anything you write in its editor.&lt;/p&gt;

&lt;p&gt;It always wants to convert '-' to an endash, '--' to an emdash, replaces
quotes with smart quotes, capitalizes random words, and so on. Those are
great things for your average dude writing some English, but man does it
suck for programmers. It's terrible for command lines too.&lt;/p&gt;

&lt;p&gt;If the code's longer than about a line, it's also pretty irritating when
you copy code from Vim, paste into Outlook, and you get plaintext. Some
people might prefer it that way, but everyone in my office uses rtf/html
formatted emails anyway, so I figured I might as well get some benefit
out of it at least.&lt;/p&gt;

&lt;p&gt;I whacked up a Vim script &quot;cliphtml&quot; that copies from Vim, using your
current colorscheme and stuffs it in the clipboard in html format.
Current requirements are Windows, Vim with +python, and pywin32
installed in your system python. Windows Vim loads the python dll from
the system location (rather than statically linking unfortunately) so
you will have to install python2.4 (at least for Vim 7.2) and pywin32 if
you're not already using Python in your Vim.&lt;/p&gt;

&lt;p&gt;To install the script, just save &lt;a href=&quot;/images/cliphtml.vim&quot;&gt;cliphtml.vim&lt;/a&gt; to
your plugins directory. The command is&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:ClipHtml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then paste into Outlook. You should get something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cliphtml_pasted.png&quot; alt=&quot;Pasted into Outlook&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It also works with ranges or visual ranges of course, so you can select
with 'V' and then :ClipHtml a snippet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mercurial (hg) with Dropbox</title>
   <link href="/2010/05/11/mercurial-hg-with-dropbox/"/>
   <updated>2010-05-11T00:00:00-07:00</updated>
   <id>/2010/05/11/mercurial-hg-with-dropbox</id>
   <content type="html">&lt;p&gt;I use Dropbox and Mercurial together so often now, and it's so freakin'
awesome.&lt;/p&gt;

&lt;p&gt;But just as I was setting up another repo, I realized that there was a
slim possibility that there's programmers out there who don't use this
trick. So they're still doing something crazy for source control, like
trying to manage an SVN server, or a P4 server, or dealing with &quot;only 1
private repo&quot; restrictions, etc.&lt;/p&gt;

&lt;p&gt;So... here it is, easy as pie. Or something that's easy, that isn't pie.
Your Mom, etc.&lt;/p&gt;

&lt;p&gt;First, &lt;a href=&quot;https://www.dropbox.com/referrals/NTMzMDU5Mzk&quot;&gt;sign up for
Dropbox&lt;/a&gt;. (That's a
referral link, you'll get an extra 250 meg on top of your free 2 gig if
you use that instead of just going to the website).&lt;/p&gt;

&lt;p&gt;Now, use Mercurial as normal. &lt;a href=&quot;http://hginit.com/01.html&quot;&gt;HgInit&lt;/a&gt; is a
decent basic tutorial. You'll probably want to install hgtk on Linux, or
TortoiseHg on Windows. But, just for example, here's the command line
version:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/myproj$ hg init
~/myproj$ hg addremove
~/myproj$ hg commit -m &quot;initial commit&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you have revisions locally, which is nice enough, but that's just
Mercurial. If your hard drive dies, you're hooped.&lt;/p&gt;

&lt;p&gt;On the other hand, you didn't have to worry about servers or making
depots, or backup, or other mucking around until you've spent at least a
few hours on the exciting new &quot;myproj&quot; and you decide you'd rather not
lose it.&lt;/p&gt;

&lt;p&gt;So, what do you do? First, clone your repo into your Dropbox:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~$ cd ~/Dropbox
~/Dropbox$ hg clone ~/myproj ~/Dropbox/myproj-hg --noupdate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The syntax is &lt;code&gt;hg clone &amp;lt;from&amp;gt; &amp;lt;to&amp;gt;&lt;/code&gt;. The &lt;code&gt;--noupdate&lt;/code&gt; flag tell
Mercurial to just store the repository data, not to check out a working
copy. You're &lt;strong&gt;never going to work directly in the Dropbox directory&lt;/strong&gt;,
but instead use it as a &quot;remote&quot; where you push and pull to and from it.
The only thing that will ever be in that directory is the &lt;code&gt;.hg&lt;/code&gt;
directory, and there's no user-serviceable parts in that particular one.
That's why I renamed &lt;code&gt;myproj&lt;/code&gt; to &lt;code&gt;myproj-hg&lt;/code&gt; in the clone step, just so
I remember that it's a Mercurial directory, and it's supposed to be
&quot;empty&quot; (because the &lt;code&gt;.hg&lt;/code&gt; will be hidden on Linux).&lt;/p&gt;

&lt;p&gt;Second step, back in your original directory, edit your paths to point at
the Dropbox backup of your repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ vim ~/myproj/.hg/hgrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(or your editor of course). Paste something like this (the file will be
new/empty if you haven't added anything else yourself:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[paths]
default = /home/sgraham/Dropbox/myproj-hg/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Replacing &quot;sgraham&quot; and &quot;myproj&quot; naturally.&lt;/p&gt;

&lt;p&gt;Now,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ hg push
$ hg pull
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will work as expected in &lt;code&gt;~/myproj&lt;/code&gt;, and every time you push, you'll
have a secure, private, offsite backup of your code.&lt;/p&gt;

&lt;p&gt;Step Three: Well, that's it. There's no more steps.&lt;/p&gt;

&lt;p&gt;When you go to another machine, say a Windows machine, all you need to
do to get access to your repository is to install Dropbox and then clone
from it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\code&amp;gt; hg clone &quot;C:\Users\sgraham\My Dropbox\myproj-hg&quot; myproj
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that's it. &lt;code&gt;hg push&lt;/code&gt; and &lt;code&gt;hg pull &amp;amp;&amp;amp; hg update&lt;/code&gt; will already work
properly.&lt;/p&gt;

&lt;p&gt;And there you have it, Dropbox is the shizzle. Along with Mercurial,
you've got two great tastes that taste better together.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Step Over in Eclipse under Ubuntu using F10</title>
   <link href="/2010/04/07/debugging-step-over-f10-eclipse-ubuntu/"/>
   <updated>2010-04-07T00:00:00-07:00</updated>
   <id>/2010/04/07/debugging-step-over-f10-eclipse-ubuntu</id>
   <content type="html">&lt;p&gt;And another for myself and search engine stumblers...&lt;/p&gt;

&lt;p&gt;If you use Eclipse on Ubuntu coming from 15-20 years of Visual Studio
you'll soon be remapping the debugging shortcut keys to match Visual
Studio's before you start swearing up a storm.&lt;/p&gt;

&lt;p&gt;However, F10 is mapped to &lt;code&gt;menubar_accel&lt;/code&gt; by something in Ubuntu. Gnome?
Metacity? Not sure what exact thing it is that steals it, but the key
doesn't make it to Eclipse anyway, so pressing F10 just opens the &lt;code&gt;File&lt;/code&gt;
menu in Eclipse which certainly isn't what you want.&lt;/p&gt;

&lt;h3&gt;The fix&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;gconf-editor&lt;/code&gt;, browse to &lt;code&gt;/desktop/gnome/interface&lt;/code&gt; then scroll
down to &lt;code&gt;menubar_accel&lt;/code&gt; and delete the &lt;code&gt;F10&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;You could probably reassign it instead, but if you're like me, you've
never used that functionality on purpose so don't bother.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Android ADT + eclim on Ubuntu 9.10</title>
   <link href="/2010/04/06/ubuntu-android-adt-eclim/"/>
   <updated>2010-04-06T00:00:00-07:00</updated>
   <id>/2010/04/06/ubuntu-android-adt-eclim</id>
   <content type="html">&lt;p&gt;Stuffing this here so I remember for next time and for search engine
stumblers...&lt;/p&gt;

&lt;p&gt;On Ubuntu (9.10) I installed Eclipse (3.5) via apt-get, then the Android
ADT per Google instructions, and then eclim via &lt;code&gt;sudo ./eclim_1.5.6.sh&lt;/code&gt;.
After installing eclim, the Android functionality in Eclipse
disappeared.&lt;/p&gt;

&lt;p&gt;I'm not sure what happened, the Android software was still listed as
being installed, but the functionality just didn't seem to be available.&lt;/p&gt;

&lt;p&gt;If instead I just install eclim into local user i.e. &lt;code&gt;./eclim_1.5.6.sh&lt;/code&gt;,
all seems well.&lt;/p&gt;

&lt;p&gt;If you got yourself into the same situation, the easiest thing I found
to do was to &quot;Completely Remove&quot; eclipse  and related packages via
Synaptic, then &lt;code&gt;sudo rm -rf /usr/lib/eclipse&lt;/code&gt; and &lt;code&gt;sudo rm -rf
~/.vim/eclim&lt;/code&gt; (or wherever you have your vimfiles), and then install
again, making sure not to install eclim as root.&lt;/p&gt;

&lt;p&gt;As a side note, I didn't know about &lt;a href=&quot;http://www.eclim.org/&quot;&gt;eclim&lt;/a&gt; until
the other day. It seems pretty sweet. You can run Eclipse headless (or
not) and then most/all your project maintainance and editing in the
sanity and comfort of Vim. Specifically, this includes proper completion
via &lt;code&gt;^X^U&lt;/code&gt; (&lt;code&gt;imap&lt;/code&gt;d to something nicer, natch) as well as error
annotations on write.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>&quot;Balanced&quot; Reporting</title>
   <link href="/2010/03/03/balanced-reporting/"/>
   <updated>2010-03-03T00:00:00-08:00</updated>
   <id>/2010/03/03/balanced-reporting</id>
   <content type="html">&lt;p&gt;Ranting on this story: &lt;a href=&quot;http://www.theaustralian.com.au/news/nation/grammar-guide-is-an-education-disaster-claims-critic/story-e6frg6nf-1225832369733&quot;&gt;Grammar guide an 'education
disaster'&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Summary: The English Teachers' Assocation of Queensland&lt;sup&gt;1&lt;/sup&gt;
published an error-filled grammar guide, a Professor of Linguistics
tried to suggest corrections, disaster resulted.&lt;/p&gt;

&lt;p&gt;It's one of those increasingly common articles where one party states
facts about a topic and another party claims an opposing viewpoint,
citing a &quot;difference of opinion&quot;. But in reality, the story is not about
two different viewpoints, it's a case of sanity versus insanity.&lt;/p&gt;

&lt;p&gt;There are objective truths. There are things not subject to one's
opinion.&lt;/p&gt;

&lt;p&gt;Anyhow, that wasn't what I was irritated about before I started typing.
The concluding paragraph of the article:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Another example is the phrase &quot;set of&quot;, as in &quot;a set of bowls&quot;, being
described as an adjective, which Professor Huddleston says is not a
grammatical unit but a noun followed by a preposition.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;No! Well, yes! But what the hell is with subordinating simple facts into
a quote to appear balanced? &quot;set of&quot; as in &quot;a set of bowls&quot; &lt;em&gt;isn't&lt;/em&gt; a
grammatical unit. &quot;set&quot; is a noun. &lt;strong&gt;&lt;em&gt;It is so&lt;/em&gt;&lt;/strong&gt;. It does not require
an authority opinion from dear Professor Huddleston.&lt;/p&gt;

&lt;p&gt;I should be more concerned about the subject of the article, but Mr.
Graham says &quot;Meh&quot;.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;And because this occasion happens to be a passable reason to offer this
link: &lt;a href=&quot;http://itre.cis.upenn.edu/~myl/languagelog/archives/001800.html&quot;&gt;some classic Dave
Barry&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;blockquote&gt;&lt;ol&gt;
&lt;li&gt;Meta-incorrectly punctuated in the article!&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>A New Old Processor</title>
   <link href="/2010/03/02/a-new-old-processor/"/>
   <updated>2010-03-02T00:00:00-08:00</updated>
   <id>/2010/03/02/a-new-old-processor</id>
   <content type="html">&lt;p&gt;&lt;em&gt;aka&lt;/em&gt; &quot;Lisp all the way down&quot;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2010/02/28/designing-hardware/&quot;&gt;Last time&lt;/a&gt; I was talking about the my
new-found excitement for designing a processor from scratch.&lt;/p&gt;

&lt;p&gt;Clearly there's a lot of previous research and art to draw on in this
area. I started going through some ancient, and some newer.&lt;/p&gt;

&lt;h3&gt;ZPU&lt;/h3&gt;

&lt;p&gt;There's a few decent processors on
&lt;a href=&quot;http://www.opencores.org/&quot;&gt;OpenCores&lt;/a&gt;: cycle accurate version of Z80s,
6502s, simple x86s, etc.&lt;/p&gt;

&lt;p&gt;There's also a neat processor called ZPU that's entirely stack based.
It's sort of assuming a pre-2000s model of computing in that RAM access
isn't (relatively) abysmally slow. It's got a very nice opcode encoding
where every opcode is 8 bits, including the immediate instruction. The
immediate opcode is &quot;high bit set&quot; and that pushes the other 7 bits as a
signed value. If you put 2+ immediates in the opcode stream, then the
previous value on the stack is shifted left and the new 7 bits are ORd
in, rather than creating a new stack value. The data bus is 32 bits, and
the rest of the 128 available opcodes are assigned to the various
standard operations, mostly operating on the stack items, but a few
include a small immediate value (again, only in the 8 bits) to allow a
displacement. This is used in the SP-relative indexers to allow local
variables to be accessed without a lot of pain. I poked around this
design for a while, and it's really nifty. I might try something like
this one, though it's kind of already &quot;been done&quot; so I'm not sure how
interesting it'd be just to reimplement that design.&lt;/p&gt;

&lt;h3&gt;Lisp Machines and SIMPLE&lt;/h3&gt;

&lt;p&gt;I didn't get too far in my pseudo-literature review before I started
looking at Lisp Machines. It turns out the actual Lisp Machines were not
really fundamentally anything that was specifically designed to run
Lisp. They did have custom microcode, and extra pointer bits for helping
on type dispatch, or helping the GC, but fundamentally, they were
&quot;regular&quot; machines that ran simple microcode, had flags, PC, stacks,
registers, conditional branching, etc.&lt;/p&gt;

&lt;p&gt;An interesting exception to this is
&lt;a href=&quot;http://docs.google.com/viewer?url=http://dspace.mit.edu/bitstream/handle/1721.1/5731/AIM-514.pdf&quot;&gt;SIMPLE&lt;/a&gt;
which at the very lowest level is actually an interpreter for a Lisp.
&lt;code&gt;car&lt;/code&gt;, &lt;code&gt;cdr&lt;/code&gt;, &lt;code&gt;cons&lt;/code&gt;, etc. are all primitive opcodes, and
computation is modelled on eval/apply'ing a recursive tree structure.&lt;/p&gt;

&lt;p&gt;That paper is very interesting. Looking back with 35 &lt;strong&gt;&lt;em&gt;years&lt;/em&gt;&lt;/strong&gt; future
vantage point on someone's University project is pretty humbling (well,
it's not &lt;em&gt;just anyone's&lt;/em&gt; University project, but still). This is a piece
of hardware that was designed with hardware garbage collection, and
evaluating properly lexically scoped closures as a computation model.
The average environment circa 1979 would have been a machine language
monitor on a 6502, or an assembler on a Z80, or a primitive BASIC
implementation. Compared to that sort of code-writing-experience, SIMPLE
blows me away. Hell, I had to write a singly-linked list &lt;code&gt;#define&lt;/code&gt;
&quot;class&quot; in plain C the other day (...which is of course just plain nuts,
but that's another story).&lt;/p&gt;

&lt;p&gt;Of course, there are some limitations to SIMPLE. Looking at it now,
limiting all memory words to homogeneous two-word cons pairs (with no
vectors/arrays) seems very constrained. This was hand-waved away by
saying that this processor could be paired with an APL processor to
handle array-based math. That it would today just be a similar NV GPU
instead doesn't say much for the advancement of our discipline.&lt;/p&gt;

&lt;p&gt;The non-realtime GC also sticks out, though there was a paper the next
year on how to make it realtime, for some definition of realtime.
Unfortunately, that paper is only available via
&lt;strike&gt;HellSpawn&lt;/strike&gt;, sorry, &lt;em&gt;ACM Digital&lt;/em&gt; &lt;strong&gt;HELLSPAWN&lt;/strong&gt;
&lt;em&gt;Library&lt;/em&gt;, so I haven't read it yet. Having a process or thread block
for a GC is one thing, having the whole processor block seems very
foreign.&lt;/p&gt;

&lt;p&gt;There's also no ALU! It's not really needed for basic evaluation, but I
think its lack is more due to wanting to demonstrate that it wasn't
necessary and saving on die space, rather than believing it didn't
belong there.&lt;/p&gt;

&lt;h3&gt;All the way...&lt;/h3&gt;

&lt;p&gt;So, SIMPLE is the basis of my plan for a new (but very old) processor.
Lisp all the way down. If all goes well, phase 2 will be trying to lift
some of those limitations if they actually turn out to be limiting.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Designing Hardware</title>
   <link href="/2010/02/28/designing-hardware/"/>
   <updated>2010-02-28T00:00:00-08:00</updated>
   <id>/2010/02/28/designing-hardware</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://dwcope.freeshell.org/projects/&quot;&gt;Dave&lt;/a&gt; and I both did the
&lt;a href=&quot;http://www1.idc.ac.il/tecs/&quot;&gt;NAND-to-Tetris&lt;/a&gt; course a while back. Actually, I
believe Dave did the whole course, but I stopped around the &quot;compiler&quot;
assignment because it was too close to what I was doing at work at the time to
be entertaining.&lt;/p&gt;

&lt;p&gt;The course was geared towards very beginner CS students which is great. It
gives a nice vertical slice of all the bits and pieces that go into getting
your average piece of code to run, and did it all in a way that was simple to
follow along with. The assignments and test cases given were excellent in the
way they walked you down the garden path very clearly, but you still felt like
you were &quot;figuring it out&quot; yourself.&lt;/p&gt;

&lt;p&gt;I work firmly in the realm of software, but that course was enough to catch a
bit of the hardware bug and have me wanting to venture below machine code.&lt;/p&gt;

&lt;p&gt;I found a few nifty/slightly crazy attempts to recreate pre-Z80-era micros
(like &lt;a href=&quot;http://www.homebrewcpu.com/&quot;&gt;Magic-1&lt;/a&gt; and &lt;a href=&quot;http://www.holmea.demon.co.uk/Mk1/Architecture.htm&quot;&gt;Mark 1
FORTH&lt;/a&gt;). Those two are
particularly crazy in that they don't use any microprocessor. The largest IC
they use is a 4-bit adder, and everything is built up from TTL 74xx series
chips (basically just and/or/flip-flops/etc.). I was all amped up to try to
build something similar, but looking at some &lt;a href=&quot;http://upload.wikimedia.org/wikipedia/commons/d/d1/Computerplatine_Wire-wrap_backplane_detail_Z80_Doppel-Europa-Format_1977.jpg&quot;&gt;wire wrap
pictures&lt;/a&gt;
and then watching Bill Buzbee's &lt;a href=&quot;http://www.youtube.com/watch?v=6UT1arQ5RNs&quot;&gt;bring-up attempts of his
CPU&lt;/a&gt; pretty much scared me off of
that idea. They look extremely cool, and I'm duly impressed, but that's a
whole lot of tedium I'm not quite prepared for yet.&lt;/p&gt;

&lt;p&gt;So, I started looking into FPGAs. Doing a CPU on FPGA isn't nearly as cool as
having your own wirewrapped CPU. Mostly because it'll just look like some
generic standard board, so when the victorious moment arrives when it finally
prints &quot;&lt;code&gt;Hello, World&lt;/code&gt;&quot; or the answer to &lt;code&gt;fib(7)&lt;/code&gt; over a serial cable,
onlookers may not be as impressed as they ought to be.&lt;/p&gt;

&lt;p&gt;However, it does turn hardware into a (relatively)
non-tedious/not-too-expensive project, so I think I'll go that way. My other
excuses are that I don't have a serial port on my computer, and TTL chips are
hard to find nowadays. &lt;a href=&quot;https://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,792&amp;amp;Prod=S3EBOARD&quot;&gt;This FPGA beginner dev
board&lt;/a&gt;
has a bunch of nifty connectors, and isn't too expensive. They have others
that are cheaper too, with less connectivity.&lt;/p&gt;

&lt;p&gt;Next time, my take on trying to come up with an interesting processor that
isn't just a generic RISC clone.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Back from the holidays &amp;mdash; brain-reboot time...</title>
   <link href="/2010/01/23/back-from-the-holiday-betterment-time/"/>
   <updated>2010-01-23T00:00:00-08:00</updated>
   <id>/2010/01/23/back-from-the-holiday-betterment-time</id>
   <content type="html">&lt;p&gt;Time to wade out of the eggnog haze, and get that old stupid brain in gear
again after a vacation.&lt;/p&gt;

&lt;p&gt;SICP revisited? Smalltalk-80? A CL project?&lt;/p&gt;

&lt;p&gt;For the first time in a while, I feel like working on something that's
explicitly focused on an incremental revenue stream.&lt;/p&gt;

&lt;p&gt;I'm pretty confident that &quot;clickware for the masses&quot; &lt;em&gt;ala&lt;/em&gt; &lt;a href=&quot;http://discuss.joelonsoftware.com/?biz&quot;&gt;Business of
Software&lt;/a&gt; is never going to make
retirement levels of income, or even daily-job-replacement levels of income,
so a minor income supplement is the goal.&lt;/p&gt;

&lt;p&gt;But in fact, I have no idea if my first idea will be saleable. So, digging
deeper, the goal isn't even really a income supplement, but instead to try to
learn whether or not there's any market for this style of software. And
assuming there is a market, whether I'm willing and able to learn the skills
required to find a sales niche in this market.&lt;/p&gt;

&lt;p&gt;The first actual product idea that came to mind in an evening of brainstorming
with my wife was a &lt;a href=&quot;http://www.internetmomma.com/&quot;&gt;decent kid-safe browser&lt;/a&gt;.
The plan in the sense of (Hopefully) Minimum Viable Product is a whitelist
built into an existing browser. I think there's a lot of room for expansion of
features and capabilities, if people want such a thing.&lt;/p&gt;

&lt;p&gt;So, off I go. In writing down the things to be done, the most obvious thing
that jumps out is that somewhere on the order of 80% of the things to be done
are not &quot;what I do&quot;. The work involved is writing sales copy, making web pages
and CSS, setting up payment processors, and so on. There's a bit of technical
evaluation, a smattering of C++ to write, but there's not a lot to that side
of things.&lt;/p&gt;

&lt;p&gt;I have &lt;em&gt;absolutely no idea how to sell software&lt;/em&gt;, despite having been making
quite a good living for the last 10 years ostensibly
&lt;a href=&quot;http://www.ea.com/&quot;&gt;selling&lt;/a&gt; &lt;a href=&quot;http://www.us.playstation.com/&quot;&gt;software&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It'd sure be a lot easier and more comfortable to jump back into that big ol'
rut, and write a library that does something neat, preferably in an obscure
language to avoid getting too many users, and then &quot;ship it&quot; by pushing to
github.&lt;/p&gt;

&lt;p&gt;So going a bit deeper still: the real meta goal is to do a brain-reboot.
Ctrl-Alt-Del me please, but maintain all of the good previous state
information.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>New Tab Page As Tasks</title>
   <link href="/2009/12/13/new-tab-page-as-tasks/"/>
   <updated>2009-12-13T00:00:00-08:00</updated>
   <id>/2009/12/13/new-tab-page-as-tasks</id>
   <content type="html">&lt;p&gt;For a while I used the little Google Tasks window in Gmail, but then for some
reason I stopped.&lt;/p&gt;

&lt;p&gt;At first I wasn't sure why I stopped using it, but then I realized that it was
because it closes itself frequently (always?), so I don't see it enough.&lt;/p&gt;

&lt;p&gt;So, in the &lt;a href=&quot;/2009/12/09/background-open-for-reader-in-chrome&quot;&gt;vein of random
tweaks&lt;/a&gt;, another Chrome
extension.&lt;/p&gt;

&lt;p&gt;This one's very simple: it just sets the &lt;a href=&quot;https://chrome.google.com/extensions/detail/bokbgdhblfolpfanocjafjhpjkebhlfk&quot;&gt;Chrome New Tab page to be Tasks&lt;/a&gt;.
Hopefully if I see them more often, I'll be more inclined to &lt;em&gt;do&lt;/em&gt; some of 'em.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Background Open For Reader In Chrome</title>
   <link href="/2009/12/09/background-open-for-reader-in-chrome/"/>
   <updated>2009-12-09T00:00:00-08:00</updated>
   <id>/2009/12/09/background-open-for-reader-in-chrome</id>
   <content type="html">&lt;p&gt;Chrome just learned how to do
&lt;a href=&quot;https://chrome.google.com/extensions/&quot;&gt;extensions&lt;/a&gt; thankfully.&lt;/p&gt;

&lt;p&gt;I was already using Chrome as my main browser, mostly because it's all-around
smokin' fast. There's minor irritations, but the Chrome team sticks to a
minimalistic and sleek world view, so the toggles I'm looking for are never
going to show up as mainline options.&lt;/p&gt;

&lt;p&gt;In addition to adding buttons and processing to Chrome, the extensions layer
enables Greasemonkey-ish &quot;content scripts&quot;. In Google Reader, the default
behaviour for the 'V' shortcut key is to open the RSS item in a new tab.
Unfortunately, it opens it in a foreground tab rather than a background tab.&lt;/p&gt;

&lt;p&gt;I like to burn through all the unread items, V-ing the ones that seem
interesting, and then later go back and read all of them. This is quite cumbersome
in Chrome when combined with non-MRU tab switching behaviour, and tab pinning.
When Reader is pinned on the left, the number of keystrokes to get back to
Reader isn't &quot;one&quot;, and it isn't even constant. So, you end up needing to grab
the mouse to get back, which is irritating.&lt;/p&gt;

&lt;p&gt;So!&lt;/p&gt;

&lt;p&gt;I made an &lt;a href=&quot;https://chrome.google.com/extensions/detail/mhlmdgjoakcfdigjjlmonhjphchebcjm&quot;&gt;extension for Chrome that adds &quot;Shift-V&quot; to Reader that opens the
selected item in a background
tab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A couple slight hacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shift-V instead of V: unfortunately, there doesn't appear to be a way to
stop propagation of the event to Reader in the API exposed to extensions
yet, so the background open can't replace the default open. Instead it has
to go on a different key binding. Occasionally, I do actually want to read
the item right away though, so I guess it handles that case. (I'd actually
rather that they were swapped so that foreground open was Shift-V, but
anyway...)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;chrome.tabs.create&lt;/code&gt; API doesn't have an option to open the tab in the
background, so instead I have to save the current (Reader) tab, open the new
tab, and then switch back to the Reader tab. On some machines (versions of
Chrome?) this causes a visible flicker, but on the current as of
right-this-minute, it doesn't seem to, so it'll do for now.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Yes, I've spent longer API spelunking and writing this post than I ever would
have spent doing Ctrl-Shift-Tab/Ctrl-PgDn.&lt;/p&gt;

&lt;p&gt;But, it's just one of those things that reduces friction and irritation and
makes me happy. Or at least sates the OCD beast for a while.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mini Jpeg Decoder</title>
   <link href="/2009/12/02/mini-jpeg-decoder/"/>
   <updated>2009-12-02T00:00:00-08:00</updated>
   <id>/2009/12/02/mini-jpeg-decoder</id>
   <content type="html">&lt;p&gt;Occasionally, I have the need to load some image data. Typically, the
data can be relatively easily converted offline to raw RGB or .TGA using
&lt;a href=&quot;http://www.imagemagick.org/&quot;&gt;ImageMagick&lt;/a&gt;. By converting ahead of time
to something simple, there's generally not much need to write
&lt;code&gt;$random_format_loader&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But, for some stuff I've been doing recently, the data's coming over the
network, or is embedded in a larger file, so it's cumbersome to modify
it as a preprocess.&lt;/p&gt;

&lt;p&gt;So, I'd like to be able to load JPEG, PNG, and DDS (which is basically a
wrapper around DXTn).&lt;/p&gt;

&lt;p&gt;Tackling JPEG first, I was a little frightened of what I might be
getting into. Most places point to libjpeg which is quite a scary huge
beast. I'm sure it's mostly huge and scary for legitimate reasons
(encoding support, various obscure variants, optimizations, etc.) but
it's not something I'm interested in having a dependency on to just load
a picture.&lt;/p&gt;

&lt;p&gt;A little hunting turned up &lt;a href=&quot;http://www.saillard.org/programs_and_patches/tinyjpegdecoder/&quot;&gt;Tiny Jpeg
Decoder&lt;/a&gt;
by Luc Saillard, and &lt;a href=&quot;http://keyj.s2000.ws/?p=137&quot;&gt;NanoJPEG&lt;/a&gt; by Martin
Fiedler. I found NanoJPEG nicer, and it's a very pleasant ~900 lines of
straight C. The resulting image from NanoJPEG looked a bit better too.&lt;/p&gt;

&lt;p&gt;I crammed Martin's implementation into &lt;em&gt;one C++ &lt;code&gt;.h&lt;/code&gt; file&lt;/em&gt; that doesn't
require any supporting &lt;code&gt;.cpp&lt;/code&gt;, and also hacked it up to be to my liking.&lt;/p&gt;

&lt;p&gt;My mashed up version doesn't use any global/static data, so I guess
there's a small benefit there if you were using it in multiple threads,
but I haven't actually exercised that.&lt;/p&gt;

&lt;p&gt;Martin's original version supports some configuration #defines for controlling
different methods of upsampling, and avoiding using use of stdlib, and so is
probably better for most people. But, here's mine anyway in case someone finds
it useful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/images/jpeg_decoder.h&quot;&gt;jpeg_decoder.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/images/jpegdecodertest.cpp&quot;&gt;jpegdecodertest.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Lightly tested on &lt;code&gt;cl vs08 win64&lt;/code&gt; and &lt;code&gt;gcc 4.4.1 x86 ubuntu&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;... PNG and DDS solutions to follow, once they're sorted out in similar
fashion.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>MinGL texturing</title>
   <link href="/2009/11/17/mingl-texturing/"/>
   <updated>2009-11-17T00:00:00-08:00</updated>
   <id>/2009/11/17/mingl-texturing</id>
   <content type="html">&lt;p&gt;In doing an old-school software triangle texture mapper, I've been trolling
through some old parts of the internet.&lt;/p&gt;

&lt;p&gt;I've found a huge amount of pages (like the semi-reborn venerable &lt;a href=&quot;http://www.3dengines.de/src_feat_accu.html&quot;&gt;3D Engines
List&lt;/a&gt;) with pages that
have fully 100% dead links.&lt;/p&gt;

&lt;p&gt;There's tons of references to flipcode.com and x2ftp.oulu.fi both of which are
long gone but well-remembered in some circles. The best reference I remembered
was Chris Hecker's articles in GDMag, and happily he's &lt;a href=&quot;http://chrishecker.com/Miscellaneous_Technical_Articles#Perspective_Texture_Mapping&quot;&gt;got them online
now&lt;/a&gt;
because I'm pretty sure my dead-tree versions are long since recycled.&lt;/p&gt;

&lt;p&gt;(As a side note, it seems like pure &lt;em&gt;Institutional Retardation&lt;/em&gt; that Chris
Hecker got laid off from Maxis.)&lt;/p&gt;

&lt;p&gt;Anyway, today &lt;a href=&quot;http://jaapsuter.com/&quot;&gt;Jaap&lt;/a&gt; (apparently a dead link also right
now), was extolling the virtues of sub-texel and sub-pixel accuracy with a
righteousness that only an ex-flipcode'r could. &lt;code&gt;:)&lt;/code&gt; Apparently the classic
test of whether you've got it right is to do a 1:1 mapping and then rotate in
2D, parallel to the near plane (i.e. around Z).&lt;/p&gt;

&lt;p&gt;So, here's MinGL doing that. I believe it's right, though the test texture
causes some bad moir&amp;eacute;. This is also quite possibly the most boring
video ever.&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=7656990&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=59a5d1&amp;amp;fullscreen=1&quot; /&gt;&lt;embed src=&quot;http://vimeo.com/moogaloop.swf?clip_id=7656990&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=59a5d1&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;512&quot; height=&quot;512&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;For a long while last week, I was convinced that I had a bug in texel
sampling. This is a little tricky to explain, but here's the situation.&lt;/p&gt;

&lt;p&gt;First, a few definitions. Texel coordinates on a 64x64 texture range from
&lt;code&gt;(-0.5, -0.5)&lt;/code&gt; at the top left, to &lt;code&gt;(63.5, 63.5)&lt;/code&gt; at the bottom right. Those
values are the extents of the &lt;em&gt;edge&lt;/em&gt; of texels, so the very centre of the top
left texel is &lt;code&gt;(0, 0)&lt;/code&gt; and the centre of the bottom right is &lt;code&gt;(63, 63)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Similarly, the screen space coordinates range from &lt;code&gt;(-0.5, -0.5)&lt;/code&gt; to
&lt;code&gt;(screenWidth - 0.5, screenHeight - 0.5)&lt;/code&gt; with the centre of the pixels being
integral coordinates.&lt;/p&gt;

&lt;p&gt;Now, if want to do a &lt;em&gt;bitblt&lt;/em&gt;, i.e. have the texture drawn at 1:1 as if it was
plain old 2D, there should be vertex positions where that will happen. And of
course there is: with the vertex and texture coordinates at &lt;code&gt;(-0.5, -0.5)&lt;/code&gt; to
&lt;code&gt;(63.5, 63.5)&lt;/code&gt;, we get a perfect 1:1 mapping. Here's a screenshot of it, blown
up after the fact:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/subtexel-offset0.png&quot; alt=&quot;Nice 1:1 mapping&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Not very exciting, but it is perfectly 1:1, which is the sort of thing 2D hud
artists will get all worked up about.&lt;/p&gt;

&lt;p&gt;However, because we're just using point-sampling, it seems it should be fine
to put the geometry anywhere. As long as the size is 64x64, then there should
always be one texel per pixel regardless of whether it's offset by the same
amount. However, when I put the vertices from &lt;code&gt;(0, 0)&lt;/code&gt; to &lt;code&gt;(64, 64)&lt;/code&gt;, I get
this artifact:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/subtexel-offset0.5.png&quot; alt=&quot;Screwy mapping&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A brief digression into texture sampling...&lt;/p&gt;

&lt;p&gt;Because we can only either light or not light individual pixels, and not
anything smaller, we want to be sure we get as close to the right colour as
possible for each pixel. Specifically, we want to sample the texture at the
texel location that represents the centre of the pixel.&lt;/p&gt;

&lt;p&gt;The triangle rasterization calculates gradients across the triangle. One of
these is how much to step in the texture when moving across a scan line. So,
to make sure that we always sample from what would be the centre of the
pixel, at the beginning of the rasterization for each line, we just make
sure to move the running sum of deltas so that it lines up with the
centre of the pixel.&lt;/p&gt;

&lt;p&gt;So, in the case where the vertex is also at a &lt;code&gt;-0.5&lt;/code&gt; offset and we're drawing
1:1, this prestep will be &lt;code&gt;0.5&lt;/code&gt;. If the vertex offset is &lt;code&gt;-0.25&lt;/code&gt; then the
prestep will be only &lt;code&gt;0.25&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, when the geometry is exactly aligned on integral coordinates, then
the prestep is &lt;code&gt;0&lt;/code&gt;. This is the &quot;edge&quot; (har-har!) case, where the vertex lies
exactly on the pixel centre, so there's no need to move at the start to align.
Because the texture's being drawn 1:1, we're advancing the texture coordinates
by 1 for every pixel, so we simply step along by 1, starting at 0.&lt;/p&gt;

&lt;p&gt;It seems like the simplest possible case.&lt;/p&gt;

&lt;p&gt;But, when actually looking up texture data the texel coordinates need to be
converted to integers, because we're just point sampling, not blending. So,
the texel coordinates have to be &lt;code&gt;ceil&lt;/code&gt;d or &lt;code&gt;floor&lt;/code&gt;d somewhere. So,
when we're stepping starting at zero, and adding one, we might get
sample data like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0.000000, 1.000000, 2.000000, 3.000000, 4.000000, 4.999999988899, 5.9999999, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, in using &lt;code&gt;floor&lt;/code&gt; or &lt;code&gt;truncate&lt;/code&gt; or &lt;code&gt;ceil&lt;/code&gt;, or anything else we've just
sampled the same texel twice when we really didn't want to. Of course, adding
a bias just masks the problem in this case, and move it to some other offset
of vertices relative to texels.&lt;/p&gt;

&lt;p&gt;This probably woudldn't be very noticable in a fixed-point rasterizer because
then the +1 step would be stable. The problem still exists for some other
fractional value that &lt;em&gt;doesn't-quite-make-it&lt;/em&gt;, but it's not when trying to do
1:1, so it probably goes undetected.&lt;/p&gt;

&lt;p&gt;It was actually very difficult to get that screenshot of the artifact too, I
had to disable the entire transformation pipeline, and pass screen coordinates
into the texture mapper, and then try various pixel offsets.&lt;/p&gt;

&lt;p&gt;Anyway, it's not really a practical problem because 1:1 geometry should just
be aligned properly in 2D, but I thought it was an interesting investigation.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>MinGL Basic Rendering Working</title>
   <link href="/2009/11/15/mingl-basic-rendering-working/"/>
   <updated>2009-11-15T00:00:00-08:00</updated>
   <id>/2009/11/15/mingl-basic-rendering-working</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;/2009/11/08-mingl-very-early-progress/&quot;&gt;Previously&lt;/a&gt;, I described my
motivation for doing something as silly as writing an underfeatured software
rasterizer in this day and age.&lt;/p&gt;

&lt;p&gt;Well, I printed out the OpenGL ES 1.x specification, and I've been doing a
little banging away. Some usual suspects that are evoking rage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSE sucks. As &lt;a href=&quot;http://www.linkedin.com/in/maxburke&quot;&gt;Max&lt;/a&gt; said on Friday, by
SSE4+, they've gotten all the way to 75% of a good vector instruction set!&lt;/li&gt;
&lt;li&gt;I wish there were better debugging environments on Ubuntu. I haven't tried
the native interface on MonoDevelop 2.2 yet, perhaps that'll save me.&lt;/li&gt;
&lt;li&gt;And of course the usual stupid C++ crap, but hey, &quot;There are only two kinds
of languages: the ones people complain about and the ones nobody uses.&quot; so
I'll skip that for today.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;It turns out that OpenGL is not greatly suited to (non-jitting) software
implementations. Even in the pared-down, less-featureful, fixed-function
version that is ES 1.0, there's an ungodly amount of insertion points where
the pipeline can be reconfigured. To avoid runtime switching in the lowest
level part of rasterization (i.e. drawing a scanline), there'd need to be
hundreds of different &quot;shaders&quot; for the fixed function. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vertex colour (bool)&lt;/li&gt;
&lt;li&gt;texture0 (bool)&lt;/li&gt;
&lt;li&gt;texture1 (bool)&lt;/li&gt;
&lt;li&gt;fog (4 possible equations)&lt;/li&gt;
&lt;li&gt;texture sampling method (6 different methods * 2 texture units)&lt;/li&gt;
&lt;li&gt;colour mask (bool)&lt;/li&gt;
&lt;li&gt;depth mask (bool)&lt;/li&gt;
&lt;li&gt;stencil mask (bool)&lt;/li&gt;
&lt;li&gt;all the fragment ops:

&lt;ul&gt;
&lt;li&gt;pixel ownership (bool)&lt;/li&gt;
&lt;li&gt;scissor (bool)&lt;/li&gt;
&lt;li&gt;alpha test (bool)&lt;/li&gt;
&lt;li&gt;stencil test (bool)&lt;/li&gt;
&lt;li&gt;depth test (bool)&lt;/li&gt;
&lt;li&gt;blending (11 blend functions)&lt;/li&gt;
&lt;li&gt;logic ops (16 logic ops)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This doesn't include any vertex level operations, just the fragment level, and
I'm sure I'm still missing some. That's also only for two texture units, which
is the minimum the specification allows. You'd have to do a couple more x2's
for each additional texture unit. Permuting out all the combinations, just
with what's there though is already 17,301,504 shaders! So, clearly that's not
going to work.&lt;/p&gt;

&lt;p&gt;It's reasonable (I guess) to make all those part of a hardware pipeline for
little additional overhead, but there's a crapload of checking, testing, and
jumping going on to do that at a software level.&lt;/p&gt;

&lt;p&gt;Another alternative would be runtime generation via JITing. This falls outside
of what MinGL is going to do. The targetted platforms include x86, x64, PPC32,
and PPC64 at a minimum which is way too much code to cram into a header.
It's also not possible to JIT on all platforms I want it to run on,
specifically Xbox 360 and PS3.&lt;/p&gt;

&lt;p&gt;So, I guess I'll have to do something like picking 10-100 of these &quot;shaders&quot;
that seem like average settings. e.g. &lt;code&gt;tex0 + depth test + noblending&lt;/code&gt;, or
&lt;code&gt;colour + no depth test + one_minus_src_alpha&lt;/code&gt;, and so on. These will become a
fast(er) path that's hopefully used 95%+ of the time, and other settings will
have to fall back on the uber-do-all-tests-at-runtime shader.&lt;/p&gt;

&lt;h3&gt;Progress&lt;/h3&gt;

&lt;p&gt;Lest it seem like all bad news, I have sorted my way through a good chunk of
the vertex pipeline, and have written a few of those fast-path shaders. Here's
the always exciting gouraud + unlit in this case, doing what's probably the 3D
version of &quot;Hello, world!&quot;: a primary coloured rotating cube.&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;512&quot; height=&quot;528&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=7621487&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=59a5d1&amp;amp;fullscreen=1&quot; /&gt;&lt;embed src=&quot;http://vimeo.com/moogaloop.swf?clip_id=7621487&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=59a5d1&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;512&quot; height=&quot;528&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;I also stuck the code up on code.google, on the off chance you want to trick
out an SSE vector math library, or show off your mad texture mapping
optimization skillZ, &lt;a href=&quot;http://code.google.com/p/mingl/source/checkout&quot;&gt;have at
it&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>mingl Very Early Progress</title>
   <link href="/2009/11/08/mingl-very-early-progress/"/>
   <updated>2009-11-08T00:00:00-08:00</updated>
   <id>/2009/11/08/mingl-very-early-progress</id>
   <content type="html">&lt;p&gt;On Friday at work, I was very irritated with the state of rendering for
demo/sample purposes. Of course at EA, there's a vast array of snazzy
engines that do asset management, post processing effects, particles,
etc., etc., and are heavily optimized for the consoles and DX9+
platforms.&lt;/p&gt;

&lt;p&gt;Unfortunately, all of this nifty functionality means that these
quite-large libraries need to interoperate and depend on other
subsystems so that they can be shared across a variety of game titles.
As a result they have a huge number of dependencies, and an enormous
footprint in conceptual API to master. The large number of dependencies
means a lot of adapters to write or find and then integrate.&lt;/p&gt;

&lt;p&gt;In practice what this means is that setting up a new test application is
a lot of work. This in turn means that someone is more likely to slap
the code for their mostly-separable library into an already-existing
game, rather than keeping it a functionally separate library as soon as
a demo or example program requires any rendering functionality.&lt;/p&gt;

&lt;p&gt;Which is where we get to the point of this post. On the way home I was
thinking &quot;How hard can it be to write a simple, no-dependency rendering
library?&quot;.&lt;/p&gt;

&lt;p&gt;What I came up with was &quot;mingl&quot;. Its goal is to be the SQLite or Lua of
rendering very simple scenes. I want it to work on &quot;all&quot; platforms, for
some definition of all, not require any configuration at all on any of
those, and be simple to understand, maintain, and integrate. Continuing
the parallel with SQLite and Lua, it certainly isn't going to be the
fastest or most featureful rendering library. No one will be shipping a
game with this library.&lt;/p&gt;

&lt;p&gt;What I've started with is a software-only implementation of OpenGL ES
1.0. It might seem like madness, and perhaps it is, but if it's
distributable as one &lt;code&gt;.cpp&lt;/code&gt; and one &lt;code&gt;.h&lt;/code&gt; that you slap into your project
to render some triangles, I'll be a happy guy. (In fact, I might try to
cram it all into inline classes to get it down to just a &lt;code&gt;.h&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;On that note, I've poked around for two evenings now and I've got enough
of the API roughed in, along with a texture mapper that would make John
Carmack, Michael Abrash, Chris Hecker, et al. cringe. If you don't
recognize those names from the days of yore... well, let's just say it
ain't going to win any speed records. But hey, it's (just barely)
working:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/texturing-working.png&quot;&gt;&lt;img src=&quot;/images/texturing-working-thumbnail.png&quot; alt=&quot;Thumbnail of first working texturing in mingl&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Performance Of Closure Compiler On Skulpt</title>
   <link href="/2009/11/05/performance-of-closure-compiler-on-skulpt/"/>
   <updated>2009-11-05T00:00:00-08:00</updated>
   <id>/2009/11/05/performance-of-closure-compiler-on-skulpt</id>
   <content type="html">&lt;p&gt;As is flying around today (at least in some very specific circles),
Google released the unfortunately named &lt;a href=&quot;http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html&quot;&gt;Closure
Tools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's 3 components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a template system,&lt;/li&gt;
&lt;li&gt;a &quot;standard&quot; library for JS (they're comparing it to STL or the JDK),&lt;/li&gt;
&lt;li&gt;a JS-to-JS compiler.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I can't say I care much about the template system, as I haven't had much
occasion to use a templating client-side. But, I need to look at it more
to understand what its intended uses are.&lt;/p&gt;

&lt;p&gt;The standard library looks pretty decent. I think the most interesting
part is definitely &lt;code&gt;goog.ui.*&lt;/code&gt; which appears to be most of the UI
widgets that are used in the building of Gmail, Maps, etc. There's some
&lt;a href=&quot;http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/&quot;&gt;demos&lt;/a&gt;
via their SVN. These aren't flashy demos, but there's broad
functionality, and (I assume) broadly cross-browser tested support here,
which is a huge time saver.&lt;/p&gt;

&lt;p&gt;And the compiler. I've been using the popular YUI compressor on
&lt;a href=&quot;http://www.skulpt.org&quot;&gt;Skulpt&lt;/a&gt;. It's easy to use, robust, and gives
good compression results.&lt;/p&gt;

&lt;p&gt;The Skulpt code seemed like a good test for the Closure compiler. Below,
&quot;selfcomp.js&quot; is a debug build of Skulpt (written in Python)
compiling itself to JavaScript. This results in a pretty big JS
file, weighing in at about a meg. Not unreasonable for a full
application though, given that the debug build is heavily commented,
and we're talking pre-minification.&lt;/p&gt;

&lt;p&gt;Below is the transcript of a quick Closure compiler test.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/skulpt$ ls -l support/tmp/selfcomp.js 
-rw-r--r-- 1 sgraham sgraham 965008 2009-11-05 00:21 support/tmp/selfcomp.js

~/skulpt$ time java -jar support/yui/yuicompressor-2.4.2.jar support/tmp/selfcomp.js \
    -o yui.js
real    0m6.340s
user    0m8.393s
sys 0m0.172s

~/skulpt$ time java -jar support/closure-compiler/compiler.jar --js support/tmp/selfcomp.js \
    --js_output_file closure.js
real    4m21.287s
user    4m27.177s
sys 0m1.660s

~/skulpt$ time java -jar support/closure-compiler/compiler.jar --js support/tmp/selfcomp.js \
    --compilation_level ADVANCED_OPTIMIZATIONS --js_output_file closure_adv.js
java.lang.RuntimeException: java.lang.RuntimeException: INTERNAL COMPILER ERROR.
...

~/skulpt$ gzip closure.js 
~/skulpt$ gzip yui.js

~/skulpt$ ls -l *.gz
-rw-r--r-- 1 sgraham sgraham 24459 2009-11-05 19:11 closure.js.gz
-rw-r--r-- 1 sgraham sgraham 40814 2009-11-05 18:31 yui.js.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yeah, almost &lt;em&gt;four and half minutes&lt;/em&gt; to compile vs. 6 seconds for the
YUI compressor. I mean, that's &lt;em&gt;fine&lt;/em&gt;, it's not like you're doing it on
every change, but it's still long enough to be irritating. It's as bad
as linking on the PS3 or 360!&lt;/p&gt;

&lt;p&gt;I haven't tracked down why the ADVANCED_OPTIMIZATIONS version doesn't
work yet. I'm sure that's a fixable problem and/or something in the
Skulpt-generated code that violates the assumptions that
closure-compiler uses. Not too worried about that.&lt;/p&gt;

&lt;p&gt;Speed improvements however, would definitely be welcomed.&lt;/p&gt;

&lt;p&gt;But, even without the &quot;advanced&quot; optimizations, the end result
post-gzipping is pretty awesome. In this case it's only 60% of the size
of the YUI version which is damn impressive.&lt;/p&gt;

&lt;h3&gt;Update&lt;/h3&gt;

&lt;p&gt;I was missing some extern declarations that caused the ICE. With those,
the advanced version completes successfully, and I'm getting damn near
close to a 50% reduction compared to YUI.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-rw-r--r-- 1 sgraham sgraham    21091 2009-11-05 20:48 closure_adv.js.gz
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Pap Music Piping</title>
   <link href="/2009/11/04/pap-music-piping/"/>
   <updated>2009-11-04T00:00:00-08:00</updated>
   <id>/2009/11/04/pap-music-piping</id>
   <content type="html">&lt;p&gt;There's this horrible, over-produced, top 40, shit music that's piped
through the office. Thankfully it's only in the stairwells, elevator
area, bathroom, etc. and not audible from anywhere near where I sit.
Though I suspect there's some poor bastard that has the Worst Cubicle
Ever that can hear it all day.&lt;/p&gt;

&lt;p&gt;Anyway, it's been like this since that phase of the building opened 3-4
years ago. So this isn't a new thing, it's been the same insipid music
ever since someone made the mistake of wiring in the possibility.&lt;/p&gt;

&lt;p&gt;The last two days though, I was sitting taking a crap and realized just
&lt;em&gt;how much&lt;/em&gt; it sucks and irritates me.&lt;/p&gt;

&lt;p&gt;Taking a huge dump is one of the best times for a complicated technical
issue to crystalize, or for the cause of a particularly nasty bug to
become obvious. It's second perhaps only to the supremely productive
meditative time during a morning shower.&lt;/p&gt;

&lt;p&gt;But no.&lt;/p&gt;

&lt;p&gt;Instead, I'm sitting listening to Miley Cyrus or Hilary Duff or
&lt;em&gt;Someone-Who-Just-Had-a-Photo-Shoot-in-&lt;/em&gt;&lt;strong&gt;Teen&lt;/strong&gt;&lt;em&gt;-With-This-Month's-Hottest-Vampire!!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have visions of smashing a screwdriver into the metal speaker grating.
I expect it'd be very satisfying.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Web Toolkit (GWT) on Karmic</title>
   <link href="/2009/10/31/google-web-toolkit-gwt-on-karmic/"/>
   <updated>2009-10-31T00:00:00-07:00</updated>
   <id>/2009/10/31/google-web-toolkit-gwt-on-karmic</id>
   <content type="html">&lt;p&gt;I wanted to try out a more recent version of GWT, it's supposed to have
support for mobile browsers as well as some other shiny stuff.&lt;/p&gt;

&lt;p&gt;I installed Eclipse on Ubuntu 9.10 (Karmic), which is the most recent version
(3.5.1). Google's got a nice plugin that you can install in one place and it
sets up templates, and installs the AppEngine SDK and the GWT SDK.&lt;/p&gt;

&lt;p&gt;So far so good.&lt;/p&gt;

&lt;p&gt;Unfortunately, when I try to run any application in Eclipse, I get this lovely
message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;** Unable to load Mozilla for hosted mode **
java.lang.UnsatisfiedLinkError: /home/sgraham/.eclipse/org.eclipse.platform_3.5.0_155965261/
plugins/com.google.gwt.eclipse.sdkbundle.linux_1.7.1.v200909221731/gwt-linux-1.7.1/
mozilla-1.7.12/libxpcom.so:
libstdc++.so.5: cannot open shared object file: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I guess there's some binary version of Mozilla they're using internally, but
it's built against an old shared stdc++ library that Karmic doesn't ship
anymore. libstdc++5 isn't installable from the repos, but I just grabbed the
&lt;code&gt;.deb&lt;/code&gt; from the Jaunty page
&lt;a href=&quot;http://packages.ubuntu.com/jaunty/i386/libstdc++5/download&quot;&gt;here&lt;/a&gt; and
installed it.&lt;/p&gt;

&lt;p&gt;And... all seems well now. I don't really know if that has any adverse effects, but I
haven't noticed anything yet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>New Software</title>
   <link href="/2009/10/26/new-software/"/>
   <updated>2009-10-26T00:00:00-07:00</updated>
   <id>/2009/10/26/new-software</id>
   <content type="html">&lt;p&gt;I've tried Wordpress, Blogger, and Tumblr (most recently), but they're a sack
of ass. The text editors are horrible and butcher the posts, and it's just
about damn impossible to paste/type code into a post and expect it to turn out
reasonable. I thought I could trade the asseyness of them for the less hassle
that a hosted service should offer, but apparently I can't.&lt;/p&gt;

&lt;p&gt;So, I sucked it up and configured &lt;a href=&quot;http://jekyllrb.com&quot;&gt;Jekyll&lt;/a&gt;. It's pretty
manual to set up, but it's just a static site generator from a
simpler-than-html-language (markdown et al.) and spits out some stuff.&lt;/p&gt;

&lt;p&gt;I went &quot;fancy&quot; (OK, not really) and used
&lt;a href=&quot;http://cufon.shoqolate.com/&quot;&gt;Cuf&amp;oacute;n&lt;/a&gt; on the headings too. It's a pretty
neat JS library+tool. It renders a font to VML + another format as data for a
JS script, so then can incrementally replace text with your custom one, either
by using VML on IE, or by using &amp;lt;canvas&gt; on all other browsers. Et voila,
&lt;em&gt;The New Yorker&lt;/em&gt;-ish heading font.&lt;/p&gt;

&lt;p&gt;Anyway, it's &lt;em&gt;easier&lt;/em&gt; to post now, and I can edit in Vim, but I probably won't
still, because, well, 140 characters about lunch is a lot less work than
writing thoughtful essays.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Team Composition</title>
   <link href="/2009/10/25/team-composition/"/>
   <updated>2009-10-25T00:00:00-07:00</updated>
   <id>/2009/10/25/team-composition</id>
   <content type="html">&lt;h3&gt;Team makeup&lt;/h3&gt;

&lt;p&gt;Pragmatist, Perfectionist, Crazy Smart&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://heroku.com/about&quot;&gt;http://heroku.com/about&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Interactions&lt;/h3&gt;

&lt;p&gt;A quote to start: This quote is the designers&amp;#8217; reflections on designing a programming language (SIMULA).&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;In the spring of 1967 a new employee at the NCC in a very shocked voice told
the switchboard operator: &amp;#8220;Two men are fighting violently in front of
the blackboard in the upstairs corridor. What shall we do?&amp;#8221; The
operator came out of her office, listened for a few seconds and then said:
&amp;#8220;Relax, it&amp;#8217;s only Dahl and Nygaard discussing SIMULA&amp;#8221;.&lt;/p&gt;

&lt;p&gt;The story is true. The SIMULA 67 language was the outcome of ten months of
an almost continuous sequence of battles and cooperation in front of that
blackboard - interrupted by intervals when we worked in our neighbouring
offices (communicating by shouting through the wall if necessary) or at
home. (The people arranging this conference asked us to provide material
relating to the development of our respective languages. We felt that the
best thing we could have done was to bring along that blackboard. But we did
not know for certain whether we would be flying a wide-body aircraft.)&lt;/p&gt;

&lt;p&gt;In some research teams a new idea is treated with loving care: &quot;How
interesting&quot;, &quot;Beautiful&quot;. This was not the case in the SIMULA development.
When one of us announced that he had a new idea, the other would brighten up
and do his best to kill it off. Assuming that the person who got the idea is
willing to fight, this is a far better mode of work than the mode of mutual
admiration. We think it was useful for us, and we succeeded in discarding a
very large number of proposals.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;(from
&lt;a href=&quot;http://www.oberon2005.ru/paper/kn1978-01e.pdf&quot;&gt;http://www.oberon2005.ru/paper/kn1978-01e.pdf&lt;/a&gt;
via &lt;a href=&quot;http://lambda-the-ultimate.org/node/3107&quot;&gt;ltu&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Isn&amp;#8217;t that &lt;strong&gt;fantastic&lt;/strong&gt;? You know that the
&quot;idea-defender&quot; here would need to quickly detach himself from any
silly latent emotional attachment to an idea. Any idea in that situation is
going have to live on its own merits.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;ve got someone who you know will rip into your shitty ideas with
pointed criticism, then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you&amp;#8217;re not going to do dumb stuff; and&lt;/li&gt;
&lt;li&gt;you&amp;#8217;re going to &lt;em&gt;know&lt;/em&gt; that you've got a winner when you get them on
board.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;That kind of relationship is a huge asset. It&amp;#8217;s one thing that turns you
into (the very cliched) &amp;#8220;more than the sum of your parts&amp;#8221;. If you
can do this, you&amp;#8217;re really combining your 2+ brains effectively.&lt;/p&gt;

&lt;p&gt;Drop your ego, cultivate these relationships, and then hang on to them for
dear life.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Really? REALLY? WTF.</title>
   <link href="/2009/07/25/really-REALLY-wtf/"/>
   <updated>2009-07-25T00:00:00-07:00</updated>
   <id>/2009/07/25/really-REALLY-wtf</id>
   <content type="html">

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;num0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;num0&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;num1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;num1&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;num2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;num2&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;num0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num2&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;str&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;num0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num2&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Someone please tell me there's a way to avoid this idiotic behaviour.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Imgburn Rocks The Shizzle</title>
   <link href="/2009/02/09/imgburn-rocks-the-shizzle/"/>
   <updated>2009-02-09T00:00:00-08:00</updated>
   <id>/2009/02/09/imgburn-rocks-the-shizzle</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/imgburn.png&quot; alt=&quot;ImgBurn&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Huzzah!</title>
   <link href="/2009/01/28/huzzah/"/>
   <updated>2009-01-28T00:00:00-08:00</updated>
   <id>/2009/01/28/huzzah</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/empty_inbox.png&quot; alt=&quot;Empty Inbox&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>First Clojure Program</title>
   <link href="/2008/11/15/first-clojure-program/"/>
   <updated>2008-11-15T00:00:00-08:00</updated>
   <id>/2008/11/15/first-clojure-program</id>
   <content type="html">&lt;p&gt;So, I watched a few of Rich&amp;#8217;s videos on &lt;a
href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt; a couple months back, but I finally got
an afternoon to spend trying it out.&lt;/p&gt;

&lt;p&gt;I skimmed through &lt;a href=&quot;http://rubyquiz.com&quot;&gt;Ruby Quiz&lt;/a&gt; to find an
interesting but simple problem, and I decide to write a &lt;a
href=&quot;http://www.rubyquiz.com/quiz5.html&quot;&gt;Sokoban&lt;/a&gt; clone.&lt;/p&gt;

&lt;p&gt;My initial thought was to do it as a gui app, but I haven&amp;#8217;t written any
Java code since JDK 1.0-alpha in late 1995, and honestly, I didn&amp;#8217;t
really feel like putting effort into learning the Java GUI API only to end up
with a bizarrely emulated, slightly broken GUI.&lt;/p&gt;

&lt;p&gt;So, I grabbed &lt;a
href=&quot;http://github.com/weavejester/compojure/tree/master&quot;&gt;Compojure&lt;/a&gt; off
of git, and made the UI a hack webapp. (Yes, it&amp;#8217;s bizarrely emulated and
slightly broken still, but at least it was easy to write).&lt;/p&gt;

&lt;p&gt;First, have a look at the result: &lt;a
href=&quot;http://h4ck3r.net:8000/&quot;&gt;Clojban!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you care, the (probably horrible and un-idiomatic) code follows.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;clojban&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:use&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compojure&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;html&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;http&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;file-utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clojure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;contrib&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;str-utils&lt;/span&gt;
                         &lt;span class=&quot;nv&quot;&gt;seq-utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clojure&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;regex&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defstruct &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defstruct &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; pos&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;:boxes&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;; set-of-pos&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;:goals&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;; set-of-pos&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;:walls&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;; set-of-pos&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;explode&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;return a pos/type seq for each char in the line&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;vector &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;struct &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iterate &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;inc&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;repeat &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line-explode&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;call explode on each line with the appropriate y&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;linesplit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Pattern&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;compile&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Pattern&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;MULTILINE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; must be a better way?&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;reduce &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;into&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;explode&lt;/span&gt;
                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iterate &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;inc&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;linesplit&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filter-level&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;extracts a set of the pos&amp;#39;s that match types&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type2&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;amp&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;; type3]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;first&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;type3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                    &lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;load-levels&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;load and return seq of level&amp;#39;s&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;contents&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;slurp &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;levelsplit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Pattern&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;compile&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;^$\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Pattern&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;MULTILINE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; each level separated by blank line&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;levels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;seq &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;levelsplit&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;levelstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;line-explode&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;levelstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;struct-map &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;
                         &lt;span class=&quot;nv&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                         &lt;span class=&quot;nv&quot;&gt;:boxes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\o&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;nv&quot;&gt;:goals&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\.&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;nv&quot;&gt;:walls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;expl-level&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\#&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Levels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;load-levels&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;sokoban_levels.txt&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LvlWidth&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LvlHeight&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PlayerRenderOpen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;♦&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PlayerRenderGoal&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;♦&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BoxRenderOpen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;▨&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BoxRenderGoal&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;▨&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WallRender&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;█&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GoalRender&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;░&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level-index&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+ &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;* &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LvlWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;



&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;render-level-layer&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;my, what an insane level representation i have here&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;items&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;if-empty&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;if-full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;remain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;seq &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;remain&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;remain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;remain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;level-index&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;recur&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\space&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;if-empty&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;if-full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
               &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rest &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;remain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;render-level&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;finallevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;reduce &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;render-level-layer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; todo how to splat `data&amp;#39;&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;replicate &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;* &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LvlWidth&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LvlHeight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;\space&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                           &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:walls&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~WallRender&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~WallRender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:goals&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~GoalRender&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~GoalRender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~BoxRenderOpen&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~BoxRenderGoal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lvl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~PlayerRenderOpen&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~PlayerRenderGoal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dotimes &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LvlHeight&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dotimes &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LvlWidth&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;finallevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;level-index&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AsciiToDx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;76&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AsciiToDy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;76&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;do-player-move&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&amp;quot;handle player movement, input is int ascii code for HJKL.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;get &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AsciiToDx&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;get &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AsciiToDy&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;curpos&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;struct &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+ &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;curpos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+ &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;curpos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;pastcandidatepos&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;struct &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+ &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;curpos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+ &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:y&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;curpos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;walls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:walls&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;boxes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;walls&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;walls&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pastcandidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pastcandidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;assoc&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:boxes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;conj &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;disj &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pastcandidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; move box&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; and player&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:player&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;candidatepos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; only player&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;JSCode&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;function postwith (p) {&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  var myForm = document.createElement(&amp;#39;form&amp;#39;);&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  myForm.method=&amp;#39;post&amp;#39;;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  myForm.action=&amp;#39;/&amp;#39;;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  for (var k in p) {&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    var myInput = document.createElement(&amp;#39;input&amp;#39;);&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    myInput.setAttribute(&amp;#39;name&amp;#39;, k);&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    myInput.setAttribute(&amp;#39;value&amp;#39;, p[k]);&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    myForm.appendChild(myInput);&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  }&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  document.body.appendChild(myForm) ;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  myForm.submit() ;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  document.body.removeChild(myForm) ;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;s&quot;&gt;function handlekey(e) {&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (!e) var e = window.event&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (e.keyCode) code = e.keyCode;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  else if (e.which) code = e.which;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (code == 37) code = 72;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (code == 38) code = 75;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (code == 39) code = 76;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (code == 40) code = 74;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;  if (code == 72 || code == 74 || code == 75 || code == 76 || code == 82 || code == 65 || code == 90) postwith({&amp;#39;code&amp;#39;: code});&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;restart-level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:complete&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:complete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:nummoves&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Levels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;next-level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;min&lt;/span&gt;
                                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;inc &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;- &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;restart-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prev-level&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dec &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;restart-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defservlet&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;clojban-servlet&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;POST&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dosync&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prevlevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;keycode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parseInt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;keycode&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;82&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;restart-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;keycode&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prev-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;keycode&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;next-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;moveresult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do-player-move&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;prevlevel&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;keycode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;difference &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:boxes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;moveresult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:goals&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;moveresult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:complete&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;conj &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:complete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;next-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:nummoves&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;inc &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:nummoves&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alter &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assoc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;moveresult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))))))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;redirect-to&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;levelstate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dosync &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;restart-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))]&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;html&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;doctype&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:xhtml-transitional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:xmlns&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:lang&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:head&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Clojban!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:meta&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:http-equiv&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:content&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;text/html; charset=utf-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:script&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:type&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;JSCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:onkeydown&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;handlekey(event);&amp;quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:style&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;font-family: arial; font-size: 13px;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:h1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:style&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;font-family: arial;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Clojban&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:p&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;This is a silly &amp;lt;i&amp;gt;Sokoban&amp;lt;/i&amp;gt; implemented in &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;link-to&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;http://clojure.org&amp;quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Clojure&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;. It&amp;#39;s hitting the server every time you move (rather than Javascript) so it might not respond too quickly. The unicode box drawing craziness looks OK in FF, and reasonable in IE, but not so hot in Chrome/Webkit. Sorry.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:table&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:style&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;border-style: none; font-size: 36px; font-family: courier; padding: 0px 0px 0px 0px; margin:0px 0px 0px 0px; line-height: 1em;&amp;quot;&lt;/span&gt;
                       &lt;span class=&quot;nv&quot;&gt;:border&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;
                       &lt;span class=&quot;nv&quot;&gt;:cellpadding&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;
                       &lt;span class=&quot;nv&quot;&gt;:cellspacing&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
               &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;with-out-str &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;render-level&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;levelstate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:p&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Use arrow keys or hjkl to move all the boxes into the goals. Press r to restart level, or a/z to give up and skip through levels.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:p&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Level: &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:curlevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:p&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Moves: &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:nummoves&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:p&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Completed: &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;str-join&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                                                     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:complete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
                                                       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;
                                                               &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;complete&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;green&amp;quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;#ccc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                                               &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                                                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;]])]))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ANY&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;page-not-found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>Configuring Vim Some More</title>
   <link href="/2008/11/10/configuring-vim-some-more/"/>
   <updated>2008-11-10T00:00:00-08:00</updated>
   <id>/2008/11/10/configuring-vim-some-more</id>
   <content type="html">&lt;p&gt;As an addendum to &lt;a
href=&quot;http://items.sjbach.com/319/configuring-vim-right&quot;&gt;http://items.sjbach.com/319/configuring-vim-right&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a few more that I think are un-live-able-without:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;vim&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;quot; ease of use keyboard mappings (why do I care about top/bottom of screen?)&lt;/span&gt;
map H ^
map L $

&lt;span class=&quot;c&quot;&gt;&amp;quot; buffer switching/management, might as well use those keys for something useful&lt;/span&gt;
map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Right&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&quot;k&quot;&gt;bnext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
imap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Right&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;ESC&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;bnext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Left&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&quot;k&quot;&gt;bprev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
imap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Left&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;ESC&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;bprev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Del&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&quot;k&quot;&gt;bd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;quot; get rid of stupid scrollbar/menu/tabs/etc&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guioptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;a

&lt;span class=&quot;c&quot;&gt;&amp;quot; don&amp;#39;t need /g after :s or :g&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;gdefault&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;quot; i prefer this to visualbell&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;noerrorbells&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;quot; Hide the mouse pointer while typing&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mousehide&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I've used all of these for longer than I can remember, probably time to troll
through recent help files and vim.org to find new and exciting juicy
settings.&lt;/p&gt;

&lt;p&gt;EDIT: forgot the one I miss the most when I don't have my .vimrc:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;vim&quot;&gt;&lt;span class=&quot;k&quot;&gt;cab&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;o&lt;/span&gt; find
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;so that :o does something useful. I'd like one of the emacs-style
smart-fuzz-file-opener command line thing, I should probably hunt around for a
plugin to do that.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bill C-61</title>
   <link href="/2008/08/24/bill-c-61/"/>
   <updated>2008-08-24T00:00:00-07:00</updated>
   <id>/2008/08/24/bill-c-61</id>
   <content type="html">&lt;p&gt;Canada&amp;#8217;s Bill C-61 is an even-worse version of the United States&amp;#8217;
DMCA.&lt;/p&gt;

&lt;p&gt;For more information, &lt;a
href=&quot;http://www.michaelgeist.ca/&quot;&gt;http://www.michaelgeist.ca/&lt;/a&gt; is a
reasonable starting point. I rolled up my sleeves and had a go at &lt;a
href=&quot;http://www2.parl.gc.ca/HousePublications/Publication.aspx?Docid=3570473&amp;amp;file=4&quot;&gt;http://www2.parl.gc.ca/HousePublications/Publication.aspx?Docid=3570473&amp;amp;file=4&lt;/a&gt;
which is relatively readable.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the letter I just posted (yes, on actual paper, in an envelope!)
to my MP.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re Canadian, please read the above links and if you don&amp;#8217;t
agree with this Bill, as I&amp;#8217;m confident you won&amp;#8217;t, phone or write
to your MP (especially if your MP is a Conservative Party member!)&lt;/p&gt;

&lt;hr /&gt;

&lt;pre&gt;&lt;code&gt;Office of the Honourable Dr. Hedy Fry, P.C., M.P.
Confederation Building House of Commons
Ottawa, Ontario
K1A 0A6

Hello Dr. Fry

I am a resident of Vancouver Centre, and I'm writing to you to express my
absolute horror at the current state of Bill C-61.

I am employed as a software engineer in the entertainment industry, and as
such, fully respect and understand the need for copyright reform in
Canada.

However, from reading this bill (at
http://www2.parl.gc.ca/HousePublications/Publication.aspx?Docid=3570473,
the reproduction rights afforded to Canadians are absolutely useless
because of section 29.21(c). This section subordinates any time-shifting
and media-shifting rights that should be allowed, merely by having any
kind of digital lock mechanism on the content. But, virtually all media
sold in Canada now contains a digital lock of some sort, so it's almost
pointless to &quot;grant&quot; these rights.

Inevitably, the devices or internet services which control the digital
lock access fail, go out of business, or otherwise are not maintained. If
we are unable to legally shift to other formats, and the media become
un-unlockable, they are effectively gone. Will all of the companies and
individuals controlling the locks exist in 5 years? Maybe. 50 years?
Unlikely.

I would also like to especially point out that this does not solely
concern things that could perhaps be considered &quot;frivolous&quot; like
pop-consumer-ish music and video. Over the next 10-15 years, it is all but
guaranteed that most books, and crucially text books, will be delivered
and consumed in electronic form. My wife is a high school teacher employed
by the Vancouver School Board, and I would be horrified to find that our
already underfunded education system had lost access to teaching
resources, simply because the company controlling a digital lock had
failed.

I sincerely hope you will make sure that this Bill is heavily modified, or
defeated, when the time comes.

Thank you for your time,

Scott Graham
*my address removed*
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Braid</title>
   <link href="/2008/08/09/braid/"/>
   <updated>2008-08-09T00:00:00-07:00</updated>
   <id>/2008/08/09/braid</id>
   <content type="html">&lt;p&gt;Braid is very cool. I often enjoyed reading &lt;em&gt;The Inner Product&lt;/em&gt; in GDMag, but
always got the impression Jonathan was a little &amp;#8220;ivory tower&amp;#8221;.
Turns out, I don&amp;#8217;t know shit. Congrats to Mr Blow! (just grabbed the
full 360 version: it&amp;#8217;s fantastic).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Floating Point</title>
   <link href="/2008/08/06/floating-point/"/>
   <updated>2008-08-06T00:00:00-07:00</updated>
   <id>/2008/08/06/floating-point</id>
   <content type="html">&lt;p&gt;Floating-point tends to chafe my ass. I was thinking perhaps I&amp;#8217;d try to really understand it. These look interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://citeseer.ist.psu.edu/goldberg91what.html&quot;&gt;http://citeseer.ist.psu.edu/goldberg91what.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cant.ua.ac.be/ieeecc754.html&quot;&gt;http://www.cant.ua.ac.be/ieeecc754.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fluorescence.fjfi.cvut.cz/~adamek/nm/ieee754.pdf&quot;&gt;http://fluorescence.fjfi.cvut.cz/~adamek/nm/ieee754.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Only way to understand something is to implement it though&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: even better by the looks of it:
&lt;a href=&quot;http://docs.sun.com/source/806-3568/ncgTOC.html&quot;&gt;http://docs.sun.com/source/806-3568/ncgTOC.html&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Second Das Keyboard</title>
   <link href="/2008/07/29/second-das-keyboard/"/>
   <updated>2008-07-29T00:00:00-07:00</updated>
   <id>/2008/07/29/second-das-keyboard</id>
   <content type="html">&lt;p&gt;So, I just got my second &lt;a
href=&quot;http://www.daskeyboard.com/&quot;&gt;http://www.daskeyboard.com/&lt;/a&gt; in the
mail. The first one I had was the &amp;#8220;original&amp;#8221;, and I loved and
continue to love it. I&amp;#8217;ve been using it as my work keyboard (where I do
the majority of my coding) for the last 3 years or so.&lt;/p&gt;

&lt;p&gt;I just got a second one, but it&amp;#8217;s the &amp;#8220;new&amp;#8221; version (the
only one they offer now). It&amp;#8217;s cleaner design-wise, but there&amp;#8217;s
some things that I think they&amp;#8217;ve made worse.&lt;/p&gt;

&lt;p&gt;The first is that the keyboard is just too thick. It&amp;#8217;s gotten half an
inch (or so) thicker. It feels more solid now, and is quite a bit heavier (so
it doesn&amp;#8217;t move around at all, which is nice), but the angle of my
forearms is slightly higher, which inevitably means my wrists are more crooked
when I get more tired and drop my arms, and slouch, etc. Don&amp;#8217;t like that
very much, especially as I&amp;#8217;ve had some wrist and arm pain recently.&lt;/p&gt;

&lt;p&gt;They also seem to have killed the variable resistance on keys (or at least
tuned them differently). The only key I notice that&amp;#8217;s harder resistance
is the backspace key, whereas the space key used to have a lot more
resistance, and doesn&amp;#8217;t all now. Perhaps the resistance has changed over
time on my original one, so it&amp;#8217;s just a matter of getting used to this
one, or breaking it in more. Maybe it&amp;#8217;s more expensive to do the bands
of keys with different resistances, but I&amp;#8217;m pretty sad about it,
especially since this one ended up being about 30% more expensive than the
original.&lt;/p&gt;

&lt;p&gt;Oh, and the F and J have icky bumps instead of being nicely scooped. :(
I&amp;#8217;m guessing that one was a concession to people who weren&amp;#8217;t very
good typists, and couldn&amp;#8217;t find the home row, but I prefer the scoops,
since we are going for &amp;#8220;stealth&amp;#8221; here, after all. They just felt
nicer on your finger tips too.&lt;/p&gt;

&lt;p&gt;The sound of the switches has changed too, but that&amp;#8217;s just&amp;#8230;
different, not really better or worse.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m going to guard my old one even more carefully now with the knowledge
that they&amp;#8217;re not &lt;i&gt;really &lt;/i&gt;replaceable. Hopefully I&amp;#8217;ll grow to
love the new one as much, but the jury&amp;#8217;s still
out.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Problems With Vinagre</title>
   <link href="/2008/07/26/problems-with-vinagre/"/>
   <updated>2008-07-26T00:00:00-07:00</updated>
   <id>/2008/07/26/problems-with-vinagre</id>
   <content type="html">&lt;p&gt;So, the default remote desktop app in Ubuntu changed from, um, I don&amp;#8217;t
know what actually, to a new app called &amp;#8220;Vinagre&amp;#8221;.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;d think that&amp;#8217;d be something I wouldn&amp;#8217;t give a patooty
about. The first thing you notice is that it has a list on the side that lets
you keep track of servers you connect to which seemed nice enough.&lt;/p&gt;

&lt;p&gt;I didn&amp;#8217;t use it much at first, so I thought nothing more about it.&lt;/p&gt;

&lt;p&gt;Today, I started using it. Dear god:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tried to connect to a fully up-to-date Fedora box (from a fully up-to-date
Ubuntu). vino-server crashes on the Fedora machine. I don&amp;#8217;t know
who&amp;#8217;s fault it is, but I don&amp;#8217;t really care. Working around that
by using XDMCP for the time being, but that&amp;#8217;s pretty irritating,
interface-wise.&lt;/li&gt;
&lt;li&gt;While repeatedly trying to connect to the Fedora box (it silently fails on
the Ubuntu machine), Vinagre doesn&amp;#8217;t save the last-entered machine
name, so I have to keep entering &amp;#8220;192.168.0&amp;#8230;.&amp;#8221; every time.
Irritating.&lt;/li&gt;
&lt;li&gt;Insanely hard to send Ctrl-Alt-Del to log into Windows machines. For same
reason, Ctrl-Alt was chosen as the &amp;#8220;Capture/Release&amp;#8221; input. So,
in order to send Ctrl-Alt-Del to login to a Windows box, you have to first
focus the Viagre app (click/whatever), then make sure you&amp;#8217;ve
&lt;strong&gt;&lt;em&gt;uncaptured&lt;/em&gt;&lt;/strong&gt; the input by doing Ctrl-Alt, then finally, &lt;strong&gt;&lt;em&gt;recapture&lt;/em&gt;&lt;/strong&gt;
the input by doing Ctrl-Alt again, and &lt;strong&gt;&lt;em&gt;then without letting go&lt;/em&gt;&lt;/strong&gt; of
Ctrl-Alt, press Del to get the final combo. If you just push that combo of
course, the Ctrl-Alt first removes capture, and then sends Ctrl-Alt-Del to
the local machine. Not very intuitive, especially since there&amp;#8217;s very
little (no?) indication of whether input is captured.&lt;/li&gt;
&lt;li&gt;Related, there seems to be absolutely no way to send F11 to the client
machine. The general hotkey behaviour is irritating enough as it is: Alt-F4
closes either all of Vinagre, or an app on the client, depending on whether
you&amp;#8217;ve pressed Ctrl-Alt recently, with no indication of which
&amp;#8220;mode&amp;#8221; you&amp;#8217;re in). But, it seems that F11 is even worse.
If you&amp;#8217;re in captured mode, then most things seem to be sent to the
target machien, but apparently F11 was deemed too important to be handled
normally, and there&amp;#8217;s no configuration mechanism. Fine, until I try to
debug something and naturally hit F11 to &amp;#8220;Step Into&amp;#8221; a function.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; When input is captured, there&amp;#8217;s no way to scroll the virtual
desktop if it&amp;#8217;s bigger than your current monitor. WTF?&lt;/p&gt;

&lt;p&gt;Basically, it just seems like this app was pushed out way too quick to the
main/default user stream. Please give me back my old VNC/RDP viewer. :(&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Windows iTunes</title>
   <link href="/2008/07/12/windows-itunes/"/>
   <updated>2008-07-12T00:00:00-07:00</updated>
   <id>/2008/07/12/windows-itunes</id>
   <content type="html">&lt;p&gt;I genuinely don&amp;#8217;t understand.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not trying to be difficult. I really tried to use iTunes this time.
It seemed like the march of inevitability if I wanted to get iPhone apps, and
I thought perhaps it would be nice to use. I grabbed the new 7.7 that has
iPhone apps, since I wanted to have a look at what was available. It was a
little large at 60meg, but hey, whatever, there&amp;#8217;s lots of bandwidth to
go around these days.&lt;/p&gt;

&lt;p&gt;First of all, I had to &lt;strong&gt;reboot&lt;/strong&gt; after installing it. Insane. Strike one. If
that was it, well fine. But it&amp;#8217;s &lt;strong&gt;&lt;em&gt;completely&lt;/em&gt;&lt;/strong&gt; unusably slow
on my laptop. The laptop is about 2 years old. It was Dell&amp;#8217;s
top-of-the-line (XPS M170) when I bought it, so it&amp;#8217;s not crazy fast, but
it&amp;#8217;s not so slow either. I&amp;#8217;m pretty sure that it&amp;#8217;s still
well above the current median machine in performance.&lt;/p&gt;

&lt;p&gt;I added my music collection (largely stored on a network drive). It&amp;#8217;s
about 65 gig, comprised mostly of mp3s and flacs, both ripped from CDs and
downloaded. Maybe a little larger than some collections, but certainly not
unreasonably large.&lt;/p&gt;

&lt;p&gt;I started the &amp;#8220;Import&amp;#8221; last night around 8pm. It&amp;#8217;s now 2pm
the next day, and it&amp;#8217;s still trying to download album artwork.
That&amp;#8217;d be fine, except that apparently while it&amp;#8217;s doing that,
it&amp;#8217;s impossible for the UI to be responsive. WTF! &lt;em&gt;Is this goddamn
amateur hour?&lt;/em&gt; It only refreshes the UI at the end of each attempt to download
an album cover?!&lt;/p&gt;

&lt;p&gt;Pausing or unpausing music, or changing the volume (since apparently it feels
the need to steal the functionality of the hardware media keys) takes over 10
seconds. That is not hyperbole! It actually takes longer than 10 seconds for
anything to happen. On top of that, the mouse event handling also appears to
be &amp;#8220;sampling&amp;#8221; rather than using the event queue properly, because
if I just click the play/pause button nothing happens. I have to &lt;strong&gt;&lt;em&gt;hold the
fucking mouse button down&lt;/em&gt;&lt;/strong&gt; until the UI responds (10 to 15 seconds,
remember!), putting the button into the down state, and then release it.&lt;/p&gt;

&lt;p&gt;On a side note, iTunes.exe currently owns roughly 300 threads, and has had a
continuous IO delta of around 500k/sec for nearly 24 hours now. Jumped up
Jesus Christ. You&amp;#8217;re not controlling air traffic, you&amp;#8217;re
cataloging and playing some fucking music.&lt;/p&gt;

&lt;p&gt;If this is Apple&amp;#8217;s shitty attempt to create some sort of Mac
&amp;#8220;halo&amp;#8221;, they&amp;#8217;ve failed miserably. With 100% certainty, I
will never, ever, by a Mac with this as the demo of the user
experience.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Project Euler, Problem 10 in F#</title>
   <link href="/2008/07/12/project-euler-problem-10-in-fs/"/>
   <updated>2008-07-12T00:00:00-07:00</updated>
   <id>/2008/07/12/project-euler-problem-10-in-fs</id>
   <content type="html">&lt;p&gt;Problem&amp;#8217;s quite simply stated this time:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.&lt;/p&gt;

&lt;p&gt;Find the sum of all the primes below two million.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;First typed in solution was simply:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1999999&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which got me a number pretty quickly that looked lovely, but was completely
wrong. I ran it again, apparently hoping that&amp;#8217;d it magically be right
the second time. Then I tried for those below 1000000 instead and the sum was
negative. Oops! So, the quick fix and working version (changing the
&amp;#8220;int&amp;#8221; range to &amp;#8220;bigint&amp;#8221; range):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1999999&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I wonder if there&amp;#8217;s a checked-overflow-arithmetic version of F#? Might
be useful for some of these questions, since they&amp;#8217;re so computationally
light anyway.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>FSharp, Euler 9</title>
   <link href="/2008/05/24/fsharp-euler-9/"/>
   <updated>2008-05-24T00:00:00-07:00</updated>
   <id>/2008/05/24/fsharp-euler-9</id>
   <content type="html">&lt;p&gt;The problem statement:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;A Pythagorean triplet is a set of three natural numbers,&lt;/p&gt;

&lt;p&gt;a&lt;sup&gt;2&lt;/sup&gt; + b&lt;sup&gt;2&lt;/sup&gt; = c&lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;For example, 3&lt;sup&gt;2&lt;/sup&gt; + 4&lt;sup&gt;2&lt;/sup&gt; = 9 + 16 = 25 = 5&lt;sup&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;There exists exactly one Pythagorean triplet for which a + b + c = 1000.&lt;/p&gt;

&lt;p&gt;Find the product abc.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is another one that&amp;#8217;s probably really more &amp;#8220;math&amp;#8221;-y
than programming-y, but I&amp;#8217;m enjoying using my new F# hammer to solve
these, so might as well keep at it.&lt;/p&gt;

&lt;p&gt;It seems like another nice make-a-sequence-and-then-filter-it, but just doing
1..1000 for a, b, and c, results in an awfully big sequence (a billion long).
So, a couple simple observations to make the numbers a lot smaller. The main
one is that you can just make c = 1000 - a - b, since we know that all answers
have to have that form anyway.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Voila!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler 8 in FSharp</title>
   <link href="/2008/05/19/euler-8-in-fsharp/"/>
   <updated>2008-05-19T00:00:00-07:00</updated>
   <id>/2008/05/19/euler-8-in-fsharp</id>
   <content type="html">&lt;p&gt;The problem:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Find the greatest product of five consecutive digits in the 1000-digit
number.&lt;/p&gt;

&lt;p&gt;73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Treating it as a number is probably not going to be too pleasant.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prob8num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;7316 ... 52963450&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prob8num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ToCharArray&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prob8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Length&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;curProd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rest&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prob8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;curProd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;prob8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So, store it as a string, but then convert it to a character array, and map to
the actual numerical values (assuming ASCII I guess).&lt;/p&gt;

&lt;p&gt;From that, just a simple recursive solution that does way too much
Array.sub&amp;#8217;ing. It would make much more sense to use List&amp;#8217;s instead
of Array&amp;#8217;s for all of those .subs, but, there was no sub extraction
built into List so I just did it that way instead.&lt;/p&gt;

&lt;p&gt;I wrestled a little with the syntax of F# again in this question. I tried
putting the &amp;#8220;let tl&amp;#8221; as inline into the body of the call to
Math.Max, but I couldn&amp;#8217;t get it to work correctly. Not sure what the
required syntax is, maybe I need some of the keywords that I don&amp;#8217;t know
from non-#light yet?&lt;/p&gt;

&lt;p&gt;Also, my copy of Expert F# has arrived, so I&amp;#8217;m just starting to peruse
it now. Hopefully my code will become more idiomatic soon enough.&lt;/p&gt;

&lt;p&gt;And man, do I hate blog software&amp;#8217;s handling of code. You&amp;#8217;d think
that maybe if I typed a less-than sign they could figure out how to escape it
moderately properly, but apparently that&amp;#8217;s way too complicated. Idiotic.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Project Euler, Problem 7 in FSharp</title>
   <link href="/2008/05/18/project-euler-problem-7-in-fsharp/"/>
   <updated>2008-05-18T00:00:00-07:00</updated>
   <id>/2008/05/18/project-euler-problem-7-in-fsharp</id>
   <content type="html">&lt;p&gt;The problem is:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6&lt;sup&gt;th&lt;/sup&gt; prime is 13.&lt;/p&gt;

&lt;p&gt;What is the 10001&lt;sup&gt;st&lt;/sup&gt; prime number?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Well, this sort of looks like another one that&amp;#8217;s intended more for
pencil-and-paper solvers than programming-language solvers. But, maybe prime
#10001 is very big, so it becomes a problem for code too. My first thought is
just to loop with a counter until we find the 10001st number, but that
involves variables which I&amp;#8217;m apparently trying to avoid in these
problems. I didn&amp;#8217;t get to use infinite lists in the last question, so
let&amp;#8217;s try again:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_infinite&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;|&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10001&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;First, we assume we have the previous prime (say it&amp;#8217;s
&amp;#8220;11&amp;#8221;). Then, we generate an infinite list starting at the next
number (i.e. [12..inf]). Then, find the first number in that list that&amp;#8217;s
prime, which is the prime after the previous one, which is the one we&amp;#8217;re
looking for. Finally, take that functionality and wrap it in a recursion
stopping at prime #1 = 2 and we&amp;#8217;re done.&lt;/p&gt;

&lt;p&gt;When I first typed this code in, I messed up the initial value for the
start of the sequence as (x + prev), which of course meant it kept finding
&amp;#8220;2&amp;#8221; as the answer. Just a dumb mistake, but the interesting part
is that I&amp;#8217;d forgotten I even had a debugger since I was getting so used
to using FSI to run bits of code. In the end I found the mistake by replacing
Seq.find with Seq.nth(0), and adding a couple Console.WriteLine()s.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;d be really nice if there was a way to put focus onto the FSI tab
window though. I find myself defining functions by using Alt-Enter on the body
of the function in the text editor, and then wanting to switch to the window
to try passing it a few values to see how it works. Without a shortcut, I have
to grab the mouse, click in the right place, sometimes Ctrl-End to find the
prompt, etc. Maybe I just haven&amp;#8217;t found the key yet, not sure.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler Project in F# Problem 6</title>
   <link href="/2008/05/15/euler-project-in-f-problem-6/"/>
   <updated>2008-05-15T00:00:00-07:00</updated>
   <id>/2008/05/15/euler-project-in-f-problem-6</id>
   <content type="html">&lt;p&gt;Kick it, Euler:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The sum of the squares of the first ten natural numbers is,&lt;/p&gt;

&lt;p&gt;1&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;2&lt;/sup&gt; + &amp;#8230; + 10&lt;sup&gt;2&lt;/sup&gt; = 385&lt;/p&gt;

&lt;p&gt;The square of the sum of the first ten natural numbers is,&lt;/p&gt;

&lt;p&gt;(1 + 2 + &amp;#8230; + 10)&lt;sup&gt;2&lt;/sup&gt; = 55&lt;sup&gt;2&lt;/sup&gt; = 3025&lt;/p&gt;

&lt;p&gt;Hence the difference between the sum of the squares of the first ten natural
numbers and the square of the sum is 3025 - 385 = 2640.&lt;/p&gt;

&lt;p&gt;Find the difference between the sum of the squares of the first one hundred
natural numbers and the square of the sum.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Not much to this one. I learned about the exponentiation operator which seems
to be a rewrite to calling a Pow method (it doesn&amp;#8217;t seem to work on
int). Here&amp;#8217;s a &amp;#8220;my brain is currently warped into thinking about
everything as a sequence and operations on sequences&amp;#8221;-solution:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(+)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;See y&amp;#8217;all next time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Dynamic Languages</title>
   <link href="/2008/05/14/dynamic-languages/"/>
   <updated>2008-05-14T00:00:00-07:00</updated>
   <id>/2008/05/14/dynamic-languages</id>
   <content type="html">&lt;blockquote&gt;&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;Because we couldn&amp;#8217;t see how the system worked anymore!&lt;/p&gt;

&lt;p&gt;Small systems are not only easier to optimize, they&amp;#8217;re possible to
optimize. And I mean globally optimize.&lt;/p&gt;

&lt;p&gt;So when we talk about performance, it&amp;#8217;s all crap. The most important
thing is that you have a small system. And then the performance will just
fall out of it naturally.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html&quot;&gt;http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler is streaking in F#, problem 5</title>
   <link href="/2008/05/13/euler-is-streaking-in-fs-problem-5/"/>
   <updated>2008-05-13T00:00:00-07:00</updated>
   <id>/2008/05/13/euler-is-streaking-in-fs-problem-5</id>
   <content type="html">&lt;p&gt;Problem #5:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.&lt;/p&gt;

&lt;p&gt;What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Speaking of infinite sequences, here&amp;#8217;s the solution that seemed obvious
to me at first.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;FSharp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Math&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_infinite&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;FromInt32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;for_all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Nice and simple, just iterate through all numbers, and find the first ne
that&amp;#8217;s evenly divisible by all the numbers from 1 to 20. Unfortunately
let it run for an hour (!) while I had dinner, and it hadn&amp;#8217;t completed.
I just assumed was doing something dumb, but it seems to give sensible answers
for the numbers in the range of 1..10 and 1..16. Apparently, at 1..17 or more
though the answer becomes &amp;#8220;quite&amp;#8221; large. The first version just
used int32&amp;#8217;s rather than BigInt; I thought perhaps it was getting past
2^32 and so never finding the answer, but it&amp;#8217;s hard to say since I
wasn&amp;#8217;t prepared to wait any longer for the BigInt version to
finish.&lt;br/&gt;&lt;br/&gt;As a side note, the bigint stuff is a bit ugly in this
example, I guess an unfortunate side effect of .NET showing through where the
numerical stack is fractured (sensibly and everything, just a little
unfortunate here).&lt;br/&gt;&lt;br/&gt;In any case, a more mathematical and less
brute-force algorithmic approach seems to be required for this
problem.&lt;br/&gt;&lt;br/&gt;Here&amp;#8217;s one that takes only milliseconds to run based
on:&lt;br/&gt;&lt;a
href=&quot;http://en.wikipedia.org/wiki/Least_common_multiple#Alternative_method&quot;&gt;http://en.wikipedia.org/wiki/Least_common_multiple#Alternative_method&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numTimes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numTimes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxNumTimes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numTimes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Pow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxNumTimes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;For all primes in the range, figure out the maximum number of times that prime
appears in the prime factorization of any of the numbers, and find the product
of those primes raised to the maximum number of powers. I learned a little F#
in this one, but as far as the math, it would have taken me a long while to
recall or figure that out, so it was basically just implementing what
Wikipedia described. Oh well.&lt;/p&gt;

&lt;p&gt;My &amp;#8220;fold&amp;#8221; got one better again, instead of passing a pointless
anon function and a pointless initial value, last time I got rid of the
function. This time I found &amp;#8220;fold1&amp;#8221; and got rid of the non-useful
initial value too! :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Some More Euler Project, Problem 4</title>
   <link href="/2008/05/12/some-more-euler-project-problem-4/"/>
   <updated>2008-05-12T00:00:00-07:00</updated>
   <id>/2008/05/12/some-more-euler-project-problem-4</id>
   <content type="html">&lt;p&gt;This one was pretty straightforward.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;A palindromic number reads the same both ways. The largest palindrome made
from the product of two 2-digit numbers is 9009 = 91 × 99.&lt;/p&gt;

&lt;p&gt;Find the largest palindrome made from the product of two 3-digit numbers.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The hardest part was just reversing the number to be able to tell if it was a
palindrome. Unfortunately, when I searched for &amp;#8220;reverse string f#&amp;#8221;
I got &lt;a
href=&quot;http://basildoncoder.com/blog/2008/04/21/project-euler-problem-4/&quot;&gt;http://basildoncoder.com/blog/2008/04/21/project-euler-problem-4/&lt;/a&gt;
which while certainly a good search result, could have ruined the fun. Anyhow:
the solution to reverse (why the heck isn&amp;#8217;t there a .Reverse on the .net
string anyway?) is the obvious thing. The only thing notable thing here is the
&amp;#8220;:string&amp;#8221; on the argument to the function which is the first time
I&amp;#8217;ve had to write a type other than the type coercions from float
&amp;lt;-&amp;gt; int. It reminds me of the irritating problem with C# generics where
it&amp;#8217;s often not possible to write the generic function because it has to
be completely generic, or has to implement an interface so the type can be
where-constrained (or in other words, generics are generics, not templates,  I
guess. The C++ approach definitely has benefits, sometimes, though.)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rev&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ToCharArray&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;999&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;999&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rev&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;After that, it&amp;#8217;s pretty simple. I just make a list of all the
palindromes created from 3 digit multiplicands, and then fold out the maximum
of those. I noticed something very dumb in the last solution, I was folding an
anonymous function that just directly passed its arguments to max, which is of
course silly. I&amp;#8217;m finding F#&amp;#8217;s syntax a little weird, but getting
better.&lt;/p&gt;

&lt;p&gt;It occurs to me after reading Mr. Basildon&amp;#8217;s solution that I don&amp;#8217;t
know the difference between Seq, List, etc. and when it matters. Maybe
it&amp;#8217;s just that seq can be infinite, vs. List is strictly an actual
memory block?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>More FSharp thoughts</title>
   <link href="/2008/05/11/more-f-thoughts/"/>
   <updated>2008-05-11T00:00:00-07:00</updated>
   <id>/2008/05/11/more-f-thoughts</id>
   <content type="html">&lt;p&gt;It&amp;#8217;s pretty irritating so far, but I can&amp;#8217;t tell if that&amp;#8217;s
because I don&amp;#8217;t know what I&amp;#8217;m doing or because I don&amp;#8217;t have
some key insight into the language structure yet, or what. I find I&amp;#8217;m
poking around a lot trying to figure out if I need a terminator or a keyword
in random places, and because of the structure of the language there&amp;#8217;s
not as many opportunities as in C# for the IDE to tell you what to type next.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s also the #light thing which is silly. The option should clearly
have been #dark (or whatever the opposite of #light is in this case) or a
command line option to make it compatible with whatever Caml dialect is
non-#light.&lt;/p&gt;

&lt;p&gt;I feel like there&amp;#8217;s things missing from Seq. and so on, but that&amp;#8217;s
more likely that I just don&amp;#8217;t know what they&amp;#8217;re called yet, or
I&amp;#8217;m expressing things incorrectly I&amp;#8217;d guess.&lt;/p&gt;

&lt;p&gt;At the same time, it&amp;#8217;s very pretty in a lot of ways. The interop with
.net (though I haven&amp;#8217;t used it yet), immumtability by default,
FSI-in-VS, and multicore-niceness are obvious wins. I don&amp;#8217;t know if
it&amp;#8217;s applicable to games yet: there&amp;#8217;d be an inordinate amount of
panic if extra computation was done unnecessarily of course. Anyway, I like it
enough apparently, I just got Amazon to fire me a copy of &amp;#8220;Expert
F#&amp;#8221;, which I hope is teh awesome.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler Problem 2 Redux</title>
   <link href="/2008/05/11/euler-problem-2-redux/"/>
   <updated>2008-05-11T00:00:00-07:00</updated>
   <id>/2008/05/11/euler-problem-2-redux</id>
   <content type="html">&lt;p&gt;This is a similar attempt, not sure if it's better or worse really, but uses comprehensions instead.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4000000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sumByInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>Euler 3</title>
   <link href="/2008/05/11/euler-3/"/>
   <updated>2008-05-11T00:00:00-07:00</updated>
   <id>/2008/05/11/euler-3</id>
   <content type="html">&lt;p&gt;The problem statement:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The first thing we need to do likely is know if a number is prime:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This is a little sneaky. First, it generates a list of numbers from 2 to the
square root of the number to be tested (square root because the largest
possible factor). Then, it uses an existence test to see if any of those
numbers can divide into the candidate number. If they can, we know it&amp;#8217;s
not prime.&lt;/p&gt;

&lt;p&gt;With that out of the way, we can attack the actual problem. My first attempt
was very C-like, to whit:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prob3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;prob3&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;600851475143&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But, that doesn&amp;#8217;t work. &amp;#8216;return&amp;#8217; doesn&amp;#8217;t exist, and
the type of &amp;#8216;for&amp;#8217; is unit, so there&amp;#8217;s no way to get the
result out. I was trying to avoid computing too many results, so going
backwards was the goal (rather than making a list of answers and filtering
them, as in the previous problems).&lt;/p&gt;

&lt;p&gt;I didn&amp;#8217;t exactly figure out how to do that, but I did come up with a
reasonable solution (at least to my non-F# eyes):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;600851475143&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isprime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;First, we make a list of all the factors of the target number that are also
prime (the comprehension). Then, fold the maximum value out of those.
It&amp;#8217;s definitely doing a lot more work than necessary, but it works OK.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s also a little bit of mucking around in this problem because the
number was bigger than 2^32-1. F# handles it reasonably cleanly though, at
least up to int64 range, by just adding some float/int/int64 calls to convert
things to the right types explicitly. Not sure what bignum looks like yet
though.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>FSharp and Project Euler</title>
   <link href="/2008/05/10/fs-and-project-euler/"/>
   <updated>2008-05-10T00:00:00-07:00</updated>
   <id>/2008/05/10/fs-and-project-euler</id>
   <content type="html">&lt;p&gt;I was vaguely looking for something that might make me smarter, wouldn&amp;#8217;t
be at all practical, and also wouldn&amp;#8217;t be a huge time investment.&lt;/p&gt;

&lt;p&gt;I started by working through the exercises of &amp;#8220;Introduction to
Algorithms&amp;#8221; by C/L/R, but I didn&amp;#8217;t make it too far. Maybe someday.&lt;/p&gt;

&lt;p&gt;Project Euler is some math/algorithmic problems that seem to fit the bill.
Since I was thinking I should learn an ML family language, I thought I&amp;#8217;d
try to solve them in F# and see how far I got.&lt;/p&gt;

&lt;p&gt;Without further ado, here&amp;#8217;s problem 1:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;If we list all the natural numbers below 10 that are multiples of 3 or 5, we
get 3, 5, 6 and 9. The sum of these multiples is 23.&lt;/p&gt;

&lt;p&gt;Find the sum of all the multiples of 3 or 5 below 1000.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;and my probably not so amazing solution:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;999&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sumByInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Not too hairy, but some neat bits:&lt;/p&gt;

&lt;p&gt;&gt; is a pipelining operator that just changes the order of the arguments.
Rather than nesting the &lt;code&gt;[1..999]&lt;/code&gt; at the end, it goes at the beginning which
makes more sense to read.&lt;/p&gt;

&lt;p&gt;And, of course, first class functions.&lt;/p&gt;

&lt;p&gt;I really hate &amp;#8220;then&amp;#8221; for whatever
repressed-loathing-of-some-crappy-language-reason, but I&amp;#8217;ll survive. I
guess.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Euler Problem 2</title>
   <link href="/2008/05/10/euler-problem-2/"/>
   <updated>2008-05-10T00:00:00-07:00</updated>
   <id>/2008/05/10/euler-problem-2</id>
   <content type="html">&lt;p&gt;(only 191 problems to go, currently)&lt;/p&gt;

&lt;p&gt;Problem #2 was stated as:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Each new term in the Fibonacci sequence is generated by adding the previous
two terms. By starting with 1 and 2, the first 10 terms will be:&lt;/p&gt;

&lt;p&gt;1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...&lt;/p&gt;

&lt;p&gt;Find the sum of all the even-valued terms in the sequence which do not
exceed four million.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Pretty straightforward I guess.&lt;/p&gt;

&lt;p&gt;let rec fib n =&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if n     else fib(n-1) + fib(n-2)
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ocaml&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4000000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sumByInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I was wondering if the 4,000,000 was supposed to try to make me do something &amp;#8220;smart&amp;#8221; because it was intended to take a long time. But, I didn&amp;#8217;t and it took about a second on my computer, even with the very dumb fib.&lt;/p&gt;

&lt;p&gt;The weakest part is the &amp;#8220;40&amp;#8221;, but I feel like F# earned me that because after I typed in the definition of fib, I used the awesome FSI (interactive F# window in Visual Studio) to quickly test what numbers would make sure I got up to at least 4M (it was 33, but 40 seemed less sneaky).&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s probably a better way to do the last line too, I guess fold over + would work. I was sort of hoping for a default Seq.sum without arguments, but I guess not. Maybe there&amp;#8217;s a shorthand way of writing the identity function?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Where's My Monitoring?</title>
   <link href="/2008/03/06/wheres-my-monitoring/"/>
   <updated>2008-03-06T00:00:00-08:00</updated>
   <id>/2008/03/06/wheres-my-monitoring</id>
   <content type="html">&lt;p&gt;Jenn and I were recently arguing about taking vitamin and other dietary
supplements. Historically, I&amp;#8217;d been rather dismissive towards them
because they always felt very pseudo-scientific, but I&amp;#8217;d never really
thought about why it was that I felt that way.&lt;/p&gt;

&lt;p&gt;Obviously it&amp;#8217;s possible that they&amp;#8217;re filling a very real need,
particularly for people who have unusual diets (we&amp;#8217;re vegetarian for
example, which isn&amp;#8217;t particularly unusual these days, but might be
considered unusual on an evolved-from-monkeys-timescale). But (and it&amp;#8217;s
a big but), there&amp;#8217;s really no practical way to know what effect of
taking these things is. You could go for a weekly battery of
blood/skin/whatever tests, but that&amp;#8217;s both costly and time-consuming.
Other than that, it falls to either correlation with secondary effects, or
&amp;#8220;how I feel&amp;#8221; both of which are way too heavily influenced by other
things going on in life and placebo effects.&lt;/p&gt;

&lt;p&gt;Visiting any supplement or &amp;#8220;natural&amp;#8221;-something-or-other store
reveals thousands of random options. The thing that really bothers me, is that
if it they turn out not to be helping, at best you&amp;#8217;re wasting a lot of
money (if they&amp;#8217;re doing nothing), but at worst, you could be creating
health problems by ingesting mixes of things that really aren&amp;#8217;t good for
you.&lt;/p&gt;

&lt;p&gt;So, getting to the point of all this, why can&amp;#8217;t I monitor myself yet?
&lt;b&gt;I think this would pretty clearly be a game-changing startup&lt;/b&gt;: I stick
my finger in a little machine before I get in the shower in the morning and it
grabs some blood and skin (and maybe occasionally I give it some hair as a
little treat). Then, it chugs away extracting as much useful information as is
possible from the samples (lots and lots and lots of info in there!). Add a
WiFi connection to it, and it doesn&amp;#8217;t need any interface at all, just
the ability to upload data to either a local machine, or preferably to a
suitably encrypted and secured web site. The web site can give me a history of
changes, monitor for flucuations, highlight defiencies (and maybe suggest
supplements or diet modifications), or tell me that now would be a damn good
idea to go see an MD or nutritionist.&lt;/p&gt;

&lt;p&gt;So, where the heck is my simple desktop monitoring system?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Foo</title>
   <link href="/2008/03/02/foo/"/>
   <updated>2008-03-02T00:00:00-08:00</updated>
   <id>/2008/03/02/foo</id>
   <content type="html">&lt;p&gt;Heard the new Foo Fighters on the radio (I assume the latest single), and all
I could think was that if Kurt had heard it, &lt;em&gt;he'd have shot himself in
the face&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;But hey, they won a Grammy or whatever. Maybe it'll be for best Adult
Contemporary next time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>bash .inputrc tab completion incantations</title>
   <link href="/2008/03/01/bash-inputrc-tab-completion-magic-incantations/"/>
   <updated>2008-03-01T00:00:00-08:00</updated>
   <id>/2008/03/01/bash-inputrc-tab-completion-magic-incantations</id>
   <content type="html">&lt;p&gt;I can&amp;#8217;t stand hitting TAB and having it do nothing because there&amp;#8217;s
two matches. Cycling seems vastly more useful to me. And, history-search (F8
in Windows), but both directions using PgUp/PgDown. I can never remember this
magic so here it is for posterity (goes in ~/.inputrc):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TAB: menu-complete
&quot;\e[Z&quot;: &quot;\e-1\C-i&quot;
&quot;\e[5~&quot;: history-search-backward
&quot;\e[6~&quot;: history-search-forward
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, Tab and Shift-Tab cycle, and PgUp/PgDown cycle through history that
matches. Much better!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Emacs For Vim</title>
   <link href="/2008/02/26/emacs-for-vim/"/>
   <updated>2008-02-26T00:00:00-08:00</updated>
   <id>/2008/02/26/emacs-for-vim</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m having a whack at trying to learn a reasonable amount of Emacs so I can attempt a project more reasonably in sbcl (and Weblocks). I&amp;#8217;ve been programming in Vim for about 12 years and my brain/hands are very, very angry at this editor transgression.&lt;/p&gt;

&lt;p&gt;Mostly because I know I&amp;#8217;ll give up, and then try again much later, here&amp;#8217;s some stuff that is permanently ingrained in my Vim brain that is the closest I could find in Emacs (so far at least). To be edited as I find more things. Vim on the left, Emacs on the right:&lt;/p&gt;

&lt;h3&gt;Movement&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;C-f, C-b = C-v, M-v&lt;/li&gt;
&lt;li&gt;hjkl = C-b, C-n, C-p, C-f&lt;/li&gt;
&lt;li&gt;HL (or ^$ for most people) = C-a, C-e&lt;/li&gt;
&lt;li&gt;wb = M-f, M-b&lt;/li&gt;
&lt;li&gt;O, o = ? (C-o does some stupid thing)&lt;/li&gt;
&lt;li&gt;u, C-r = ?&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Change/Deleting&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;das = ?&lt;/li&gt;
&lt;li&gt;cab = ?&lt;/li&gt;
&lt;li&gt;gqap = ?&lt;/li&gt;
&lt;li&gt;dd = ?&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Clipboard&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&quot;+y = ?&lt;/li&gt;
&lt;li&gt;&quot;+P = ?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The page movement commands are probably my biggest problem right now: for one they&amp;#8217;re the dumb ones like Vim&amp;#8217;s C-u/C-d that only move half a page (haven&amp;#8217;t figured out how to make them only leave one line instead yet), and for two, it&amp;#8217;s just kind of painful because you have to move your pinky and then repress the v, rather than just hold down control and toggle between f/b. Anyway, whatever. I&amp;#8217;ll suck and use PgUp/PgDn for now.&lt;/p&gt;

&lt;p&gt;No hjkl of course kills me, but everyone else too.&lt;/p&gt;

&lt;p&gt;I keep hitting Esc when I&amp;#8217;m done entering text so then the next Ctrl/Meta command doesn&amp;#8217;t work because it&amp;#8217;s been prefixed by an Escape. Ack. Pffft.&lt;/p&gt;

&lt;p&gt;The most amusing thing so far is that I couldn&amp;#8217;t figure out enough to edit my .emacs in Emacs so the first few edits were:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ vim ~/.emacs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hrm.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Javascript Framework</title>
   <link href="/2008/02/22/javascript-framework/"/>
   <updated>2008-02-22T00:00:00-08:00</updated>
   <id>/2008/02/22/javascript-framework</id>
   <content type="html">&lt;p&gt;I thought I liked jQuery, but it&amp;#8217;s just a bit too weird after using it
for a bit. I kept having the feeling that it was too much magic and not enough
JavaScript. So, I&amp;#8217;m using &lt;a href=&quot;http://mootools.net/&quot;&gt;mootools&lt;/a&gt;
now. It&amp;#8217;s very similar, but one or both of the design and documentation
is better, and as a result I&amp;#8217;m much happier with it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>N Plus</title>
   <link href="/2008/02/21/n-plus/"/>
   <updated>2008-02-21T00:00:00-08:00</updated>
   <id>/2008/02/21/n-plus</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.slickentertainment.com/?page_id=3&quot;&gt;N+&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nick and Kees over at Slick Entertainment just had their 360 XBLA version of
&amp;#8220;N&amp;#8221; (a cool platformer) released today. Just grabbed the full
version and it&amp;#8217;s a heck of a lot of fun.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Arcish Web Programming In Python</title>
   <link href="/2008/02/02/arcish-web-programming-in-python/"/>
   <updated>2008-02-02T00:00:00-08:00</updated>
   <id>/2008/02/02/arcish-web-programming-in-python</id>
   <content type="html">&lt;p&gt;There seems to be little more sanity coming to the Arc discussion. Some people
are still paniced about HTML generation, but I&amp;#8217;m not sure that you
really have to use that if you don&amp;#8217;t like it. Others are just
disappointed because they were hoping for &amp;#8230; I don&amp;#8217;t know what,
some sort of Holy Grail, but it&amp;#8217;s, &lt;em&gt;y'know&lt;/em&gt;, just a programming
language.&lt;/p&gt;

&lt;p&gt;The terseness it brings to common web expressions is quite pleasant though,
and I wanted to be able to have a similar level of power and terseness in
Python if possible. I spent a little time putting together
&amp;#8220;pyflow&amp;#8221; (named for both the nicer control-flow primitives and,
hopefully, a state of mind for its users). The &amp;#8220;&lt;a
href=&quot;http://arclanguage.org/item?id=722&quot;&gt;Arc Challenge&lt;/a&gt;&amp;#8221; code looks
like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@opapp&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;said&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;you said: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                  &lt;span class=&quot;s&quot;&gt;&amp;quot;click here&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It&amp;#8217;s 19 tokens (which is 4 more than the Arc version), but I still find
it nice to read. I prefer &amp;#8220;foo&amp;#8221; being passed as a real parameter
(vs. (arg _ &amp;#8220;foo&amp;#8221;) in Arc), but the cede()&amp;#8217;s are somewhat
less pleasant on the Python side.&lt;/p&gt;

&lt;p&gt;Moving to a reimplementation of  blog.arc, pyflow fares better.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getstorelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BlogTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;A Blog&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;blogPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defpage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fixed600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;h1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;blog&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BlogTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;withsepbull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;archive&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;newpost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;new post&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))),&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlogTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;viewpost?id=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;notfound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blogPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;spacedp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;No such post.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;displayPost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;h2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;editpost?id=&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;[edit]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;spacedp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;markdown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;body&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    
&lt;span class=&quot;nd&quot;&gt;@opapp&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blogPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displayPost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])]))&lt;/span&gt;
    
&lt;span class=&quot;nd&quot;&gt;@op&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;li&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blogPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@op&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewpost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notfound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@oplogin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newpost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defpage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;aform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withsepbr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;t&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;new post&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        
&lt;span class=&quot;nd&quot;&gt;@oplogin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;editpost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defpage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;aform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withsepbr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;t&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;body&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;edit post&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kind of long for Wordpress&amp;#8217;s asinine (non-)code handling, but quite
short given the functionality that&amp;#8217;s in there. (I got lazy on editpost,
it should really share code with newpost). Wins over the Arc code include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple persistent list/dict built in&lt;/strong&gt;. A lot of the fiddling in the Arc
code is to load/store/iterate over numbered files in the &amp;#8216;posts&amp;#8217;
directory. pyflow includes a simple transactional dict/list store for simple
storage (that also happens to work when there&amp;#8217;s concurrent users, which
I don&amp;#8217;t think blog.arc would do right now).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python functionality that&amp;#8217;s somewhat terser than Arc&lt;/strong&gt;. For
example, the main entry point &amp;#8220;/blog&amp;#8221; looks like this in
blog.arc:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cl&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defop&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;blogpage&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;awhen&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;posts*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;maxid*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;display-post&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;vs. in pyflow, it looks like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@opapp&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blogPage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displayPost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;List comprehension work nicely here to keep the number of tokens down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;: Some of the layout-y (e.g. (br 3)) code that ends up being code in
Arc is in a default.css which also allows for snazzing things up pretty
easily. Although, I got lazy so there&amp;#8217;s some formatting in the code in
pyflow that could be tidied up and shortened.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t mean to imply the blog code couldn&amp;#8217;t be squished down more
in Arc (I&amp;#8217;m sure it could), or that I don&amp;#8217;t like Arc&amp;#8217;s
approach, but I think it&amp;#8217;s worth exploring how similar idioms can be
expressed in various languages to try to improve everyone&amp;#8217;s end
solution. Perhaps when Paul releases &amp;#8220;news&amp;#8221;, I&amp;#8217;ll have a
chance to see if Arc is more of a win on larger and more production-quality
code bases.&lt;/p&gt;

&lt;p&gt;Anyhow, I think the discussion surrounding Arc is the best thing that&amp;#8217;s
happening right now. So, if you&amp;#8217;re contributing, keep it up. Lots of
interesting stuff coming out. If anyone has any suggestions on how the pyflow
example code could be simplified with new idioms, please fire
away.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Better Flow Control</title>
   <link href="/2008/02/01/better-flow-control/"/>
   <updated>2008-02-01T00:00:00-08:00</updated>
   <id>/2008/02/01/better-flow-control</id>
   <content type="html">&lt;p&gt;Been poking around the Arc site; I did a quick &lt;a
href=&quot;http://h4ck3r.net/vimarc0.tar.gz&quot;&gt;Vim integration&lt;/a&gt; (to allow sending
files/forms to the running Arc process), and I&amp;#8217;ve been reading its code
a little, mostly to get a better understanding of the approach it&amp;#8217;s
taking for html generation.&lt;br/&gt;&lt;br/&gt;There&amp;#8217;s bad and good, but
it&amp;#8217;s certainly &lt;a href=&quot;http://arclanguage.com/item?id=722&quot;&gt;very
terse&lt;/a&gt;. Here&amp;#8217;s the Arc version of prompt, interstitial, and results:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cl&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defop&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;said&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;aform&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;[w/link&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;you said: &amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;click here&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I&amp;#8217;d written a Python library that makes things pretty terse
(there&amp;#8217;s an example on that page), but after seeing the Arc version, I
wanted to trim it down some more. It now looks like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@op&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;said&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;you said: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;s&quot;&gt;&amp;quot;click here&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cede&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;There&amp;#8217;s a bit of magic going on, but it&amp;#8217;s quite nice and
tidy I think.  Compared to the Arc version, I prefer having &lt;code&gt;foo&lt;/code&gt; as a
regular argument to the handler function vs &lt;code&gt;(arg _ foo)&lt;/code&gt; in Arc, but
the simpler closures in Arc allow you to avoid &lt;code&gt;cede&lt;/code&gt; and the name
&lt;code&gt;result&lt;/code&gt; which is a little nicer. It's pretty close to a direct
translation which I find interesting. I'll definitely be keeping an eye
on Arc as it develops, I found this an expanding experience.&lt;/p&gt;
</content>
 </entry>
 
</feed>

