<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Advogato blog for joey</title>
    <link>http://www.advogato.org/person/joey/</link>
    <description>Advogato blog for joey</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Sat, 25 May 2013 11:28:12 GMT</pubDate>
    <item>
      <pubDate>Wed, 8 May 2013 20:04:23 GMT</pubDate>
      <title>faster dh</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=519</link>
      <guid>http://joeyh.name/blog/entry/faster_dh/</guid>
      <description>&lt;p&gt;With wheezy released, the floodgates are opened on a lot of debhelper
changes that have been piling up. Most of these should be pretty minor, but
I released one yesterday that will affect all users of &lt;code&gt;dh&lt;/code&gt;. Hopefully in a
good way.&lt;/p&gt;

&lt;p&gt;I made &lt;code&gt;dh&lt;/code&gt; smarter about selecting which debhelper commands it runs.
It can tell when a package does not use the stuff done by a particular
command, and skips running the command entirely.&lt;/p&gt;

&lt;p&gt;So the &lt;code&gt;debian/rules binary&lt;/code&gt; of a package using &lt;code&gt;dh&lt;/code&gt;
will now often look like this:&lt;/p&gt;

&lt;pre&gt;
dh binary
   dh_testroot
   dh_prep
   dh_auto_install
   dh_installdocs
   dh_installchangelogs
   dh_perl
   dh_link
   dh_compress
   dh_fixperms
   dh_installdeb
   dh_gencontrol
   dh_md5sums
   dh_builddeb
&lt;/pre&gt;


&lt;p&gt;Which is pretty close to the optimal hand-crafted &lt;code&gt;debian/rules&lt;/code&gt; file (and just
about as fast, too). But with the benefit that if you later add, say, cron job
files, &lt;code&gt;dh_installcron&lt;/code&gt; will automatically start being run too.&lt;/p&gt;

&lt;p&gt;Hopefully this will not result in any behavior changes, other than packages
building faster and with less noise. If there is a bug it'll probably
be something missing in the specification of when a command needs to be run.&lt;/p&gt;

&lt;p&gt;Beyond speed, I hope that this will help to lower the bar to adding new
commands to debhelper, and to the default dh sequences. Before, every such
new command slowed things down and was annoying. Now more special-purpose
commands won't get in the way of packages that don't need them.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;The way this works is that debhelper commands can include a "PROMISE"
directive. An example from &lt;code&gt;dh_installexamples&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;
  &lt;code&gt;# PROMISE: DH NOOP WITHOUT examples
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Mostly this specifies the files in &lt;code&gt;debian/&lt;/code&gt; that are used by the command, and
whose presence triggers the command to run. There is also a syntax to specify
items that can be present in the package build directory to trigger the command
to run.&lt;/p&gt;

&lt;p&gt;(Unfortunatly, &lt;code&gt;dh_perl&lt;/code&gt; can't use this. There's no good way to specify
when &lt;code&gt;dh_perl&lt;/code&gt; needs to run, short of doing nearly as much work as &lt;code&gt;dh_perl&lt;/code&gt;
would do when run. Oh well.)&lt;/p&gt;

&lt;p&gt;Note that third-party &lt;code&gt;dh_&lt;/code&gt; commands can include these directives too, if that
makes sense.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;I'm happy how this turned out, but I could be happier about the implementation.
The PROMISE directives need to be maintained along with the code of the
command. If another config file is added, they obviously must be updated.
Other changes to a command can invalidate the PROMISE directive, and cause
unexpected bugs.&lt;/p&gt;

&lt;p&gt;What would be ideal is to not repeat the inputs of the command in these
directives, but instead write the command such that its inputs can be
automatically extracted. I played around with some code like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;&lt;span&gt;$behavior&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;main_behavior&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"docs tmp(usr/share/doc/)"&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;sub&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
       &lt;span&gt;my&lt;/span&gt; &lt;span&gt;$package&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;shift&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
       &lt;span&gt;my&lt;/span&gt; &lt;span&gt;$docs&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;shift&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
       &lt;span&gt;my&lt;/span&gt; &lt;span&gt;$docdir&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;shift&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

       &lt;span&gt;install&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$docs&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;$docdir&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;});&lt;/span&gt;
&lt;span&gt;$behavior&lt;/span&gt;&lt;span&gt;-&amp;gt;(&lt;/span&gt;&lt;span&gt;$package&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But refactoring all debhelper commands to be written in this style
would be a big job. And I was not happy enough with the flexability
and expressiveness of this to continue with it.&lt;/p&gt;

&lt;p&gt;I can however, dream about what this would look like if debhelper were written
in Haskell. Then I would have a &lt;code&gt;Debhelper a&lt;/code&gt; monad, within which each command
executes.&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;main &lt;span&gt;=&lt;/span&gt; runDebhelperIO installDocs

installDocs &lt;span&gt;::&lt;/span&gt; Monad a &lt;span&gt;=&amp;gt;&lt;/span&gt; Debhelper a
installDocs &lt;span&gt;=&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
    docs &lt;span&gt;&amp;lt;-&lt;/span&gt; configFile &lt;span&gt;"docs"&lt;/span&gt;
    docdir &lt;span&gt;&amp;lt;-&lt;/span&gt; tmpDir &lt;span&gt;"usr/share/doc"&lt;/span&gt;
    lift &lt;span&gt;$&lt;/span&gt; install docs docdir
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;To run the command, &lt;code&gt;runDebhelperIO&lt;/code&gt; would loop over all the packages
and run the action, in the &lt;code&gt;Debhelper IO&lt;/code&gt; monad.&lt;/p&gt;

&lt;p&gt;But, this also allows making an &lt;code&gt;examineDebhelper&lt;/code&gt; that takes an action
like &lt;code&gt;installDocs&lt;/code&gt;, and runs it in a &lt;code&gt;Debhelper Writer&lt;/code&gt; monad. That would
accumulate a list of all the inputs used by the action, and return it,
without performing any side effecting IO actions.&lt;/p&gt;

&lt;p&gt;It's been 15 years since I last changed the language debhelper was written
in. I did that for less gains than this, really. (The issue back then was
that shell &lt;code&gt;getopt&lt;/code&gt; sucked.) IIRC it was not very hard, and only took a few
days. Still, I don't really anticipate reimplementing debhelper in Haskell
any time soon.&lt;/p&gt;

&lt;p&gt;For one thing, individual Haskell binaries are quite large, statically
linking all Haskell libraries they use, and so the installed size of
debhelper would go up quite a bit. I hope that forthcoming changes will
move things toward dynamically linked haskell libraries, and make it more
appealing for projects that involve a lot of small commands.&lt;/p&gt;

&lt;p&gt;So, just a thought experiment for now..&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 2 May 2013 17:04:11 GMT</pubDate>
      <title>the #newinwheezy game: STM</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=518</link>
      <guid>http://joeyh.name/blog/entry/the_newinwheezy_game:_STM/</guid>
      <description>&lt;p&gt;Debian wheezy includes a bunch of excellent new Haskell libraries.
I'm going to highlight one that should be interesting to non-Haskell
developers, who may have struggled with writing non-buggy threaded
programs in other languages:
&lt;a href="http://packages.debian.org/wheezy/libghc-stm-dev" &gt;libghc-stm-dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had given up on most threaded programs before learning about
&lt;a href="http://en.wikipedia.org/wiki/Software_transactional_memory" &gt;Software Transactional Memory&lt;/a&gt;.
Writing a correct threaded program, when multiple threads needed
to modify the same state, needed careful uses of locking.
In my experience, locking is almost never gotten right the first time.&lt;/p&gt;

&lt;p&gt;A real life example I encountered is an app that displays a queue of files
to be downloaded, and a list of files currently downloading. Starting
a new download would go something like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;startDownload &lt;span&gt;=&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
    file &lt;span&gt;&amp;lt;-&lt;/span&gt; getQueuedFile
    push file currentDownLoads
    startDownloadThread file
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But there's a point in time in which another thread, that refreshes the
display, could then see an inconsistent state, where the file is in neither
place. To fix this, you'd need to add lock checking around all accesses to
the download queue and current downloads list, and lock them both here.
(And be sure to always take the locks in the same order!)&lt;/p&gt;

&lt;p&gt;But, it's worse than that, because how is &lt;code&gt;getQueuedFile&lt;/code&gt; implemented?
If the queue is empty, it needs to wait on a file being added. But how
can a file be added the queue if we've locked it in order to perform this
larger &lt;code&gt;startDownload&lt;/code&gt; operation? What should be really simple code
has become really complex juggling of locks.&lt;/p&gt;

&lt;p&gt;STM deals with this in a much nicer way:&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;startDownload &lt;span&gt;=&lt;/span&gt; atomically &lt;span&gt;$&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
    file &lt;span&gt;&amp;lt;-&lt;/span&gt; getQueuedFile
    push file currentDownLoads
    startDownloadThread file
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now the two operations are performed as one atomic transaction. It's not
possible for any other thread to see an inconsistent state. No explicit
locking is needed.&lt;/p&gt;

&lt;p&gt;And, &lt;code&gt;getQueuedFile&lt;/code&gt; can do whatever waiting it needs to, also using STM.
This becomes part of the same larger transaction, in a way that cannot
deadlock. It might be implemented like this:&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;getQueuedFile &lt;span&gt;=&lt;/span&gt; atomically &lt;span&gt;$&lt;/span&gt;
    &lt;span&gt;if&lt;/span&gt; &lt;span&gt;empty&lt;/span&gt; downloadQueue
        &lt;span&gt;then&lt;/span&gt; retry
        &lt;span&gt;else&lt;/span&gt; pop downloadQueue
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;When the queue is empty and this calls "retry", STM automatically waits
for the queue to change before restarting the transaction. So this blocks
until a file becomes available. It does it without any locking, and without
you needing to tell explicitly tell STM what you're waiting on.&lt;/p&gt;

&lt;p&gt;I find this beautiful, and am happier with it the more I use it in my code.
Functions like &lt;code&gt;getQueuedFile&lt;/code&gt; that run entirely in STM are building blocks
that can be snapped together without worries to build more and more complex
things.&lt;/p&gt;

&lt;p&gt;For non-Haskell developers, STM is also available in Clojure, and work
is underway to add it to gcc. There is also Hardware Transactional Memory
coming, to speed it up. Although in my experience it's quite acceptably
fast already.&lt;/p&gt;

&lt;p&gt;However, as far as I know, all these other implementations of STM leave
developers with a problem nearly as thorny as the original problem with
locking. STM inherently works by detecting when a change is made that
conflicts with another transaction, throwing away the change,
and retrying. This means that code inside a STM transaction may
run more than once.&lt;/p&gt;

&lt;p&gt;Wait a second.. Doesn't that mean this code has a problem?&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;startDownload &lt;span&gt;=&lt;/span&gt; atomically &lt;span&gt;$&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
    file &lt;span&gt;&amp;lt;-&lt;/span&gt; getQueuedFile
    push file currentDownLoads
    startDownloadThread file
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Yes, this code is buggy! If the download thread is started, but then STM
restarts the transaction, the same file will be downloaded repeatedly.&lt;/p&gt;

&lt;p&gt;The C, Clojure, etc, STM implementations all let you write this buggy
code.&lt;/p&gt;

&lt;p&gt;Haskell, however, does not. The buggy code I showed won't even compile. The
way it prevents this involves, well, monads. But essentially, it is able to
use type checking to automatically determine that &lt;code&gt;startDownloadThread&lt;/code&gt; is
not safe to put in the middle of a STM transaction. You're left with no
choice but to change things so the thread is only
spawned once the transaction succeeds:&lt;/p&gt;

&lt;div&gt;
  &lt;pre&gt;startDownload &lt;span&gt;=&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
    file &lt;span&gt;&amp;lt;-&lt;/span&gt; atomically &lt;span&gt;$&lt;/span&gt; &lt;span&gt;do&lt;/span&gt;
        f &lt;span&gt;&amp;lt;-&lt;/span&gt; getQueuedFile
        push file currentDownLoads
        &lt;span&gt;return&lt;/span&gt; f
    startDownloadThread file
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you appreciate that, you may want to check out some other #newinwheezy stuff like
&lt;a href="http://packages.debian.org/wheezy/libghc-stm-dev" &gt;libghc-yesod-dev&lt;/a&gt;,
a web framework that uses type checking to avoid broken urls,
and also makes heavy use of threading, so is a great fit for using with
STM. And
&lt;a href="http://packages.debian.org/wheezy/libghc-quickcheck2-dev" &gt;libghc-quickcheck2-dev&lt;/a&gt;,
which leverages the type system to automatically test properties about your
program.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Wed, 17 Apr 2013 07:04:18 GMT</pubDate>
      <title>Template Haskell on impossible architectures</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=517</link>
      <guid>http://joeyh.name/blog/entry/Template_Haskell_on_impossible_architectures/</guid>
      <description>&lt;p&gt;Imagine you had an excellent successful Kickstarter campaign, and during
it a lot of people asked for an Android port to be made of the software.
Which is written in Haskell. No problem, you'd think -- the user interface
can be written as a local webapp, which will be nicely platform agnostic
and so make it easy to port. Also, it's easy to promise a lot of stuff
during a Kickstarter campaign. Keeps the graph going up. What could go
wrong?&lt;/p&gt;

&lt;p&gt;So, rather later you realize there is no Haskell compiler for Android. At
all. But surely there will be eventually. And so you go off and build the
webapp. Since Yesod seems to be the pinnacle of type-safe Haskell web
frameworks, you use it. Hmm, there's this Template Haskell stuff that it
uses a lot, but it only makes compiles a little slow, and the result is
cool, so why not.&lt;/p&gt;

&lt;p&gt;Then, about half-way through the project, it seems time to get around
to this Android port. And, amazingly, a
&lt;a href="https://github.com/neurocyte/ghc-android" &gt;Haskell compiler for Android&lt;/a&gt;
has appeared in the meantime. Like the Haskell community has your back.
(Which they generally seem to.) It's early days and rough, lots of libraries
need to be hacked to work, but it only takes around 2 weeks to get a
port of your program that basically works.&lt;/p&gt;

&lt;p&gt;But, no webapp. Cause nobody seems to know how to make a cross-compiling
Haskell compiler do Template Haskell. (Even building a fully native
compiler on Android doesn't do the trick. Perhaps you missed something
though.)&lt;/p&gt;

&lt;p&gt;At this point you can give up and write a separate Android UI (perhaps
using these new &lt;a href="https://github.com/neurocyte/foreign-jni" &gt;Android JNI bindings for Haskell&lt;/a&gt; that have also
appeared in the meantime). Or you can procrastinate for a while, and mull
it over; consider rewriting the webapp to not use Yesod but some other
framework that doesn't need Template Haskell.&lt;/p&gt;

&lt;p&gt;Eventually you might think this: If I run &lt;code&gt;ghc -ddump-splices&lt;/code&gt; when I'm
building my Yesod code, I can see all the thousands of lines of delicious
machine generated Haskell code. I just have to paste that in, in
place of the Template Haskell that generated it, and I'll get a program I
can build on Android! What could go wrong?&lt;/p&gt;

&lt;p&gt;And you even try it, and yeah, it seems to work. For small amounts of code
that you paste in and carefully modify and get working. Not a whole
big, constantly improving webapp where every single line of html gets
converted to types and lambdas that are somehow screamingly fast.&lt;/p&gt;

&lt;p&gt;So then, let's automate this pasting.
And so the &lt;a href="http://source.git-annex.branchable.com/?p=source.git;a=blob;f=Build/EvilSplicer.hs" &gt;EvilSplicer&lt;/a&gt; is born!&lt;/p&gt;

&lt;p&gt;That's a fairly general-purpose Template Haskell splicer. First do a native
build with -ddump-splices output redirected to a log file. Run the
EvilSplicer to fix up the code. Then run an Android cross-compile.&lt;/p&gt;

&lt;p&gt;But oh, the caveats. There are so many ways this can go wrong..&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;The first and most annoying problem you'll encounter is
that often Template Haskell splices refer to hidden symbols that
are not exported from the modules that define the splices.
This lets the splices use those symbols, but prevents them being used in
your code.&lt;/p&gt;

&lt;p&gt;This does not seem like a good part of the Template Haskell design,
to be honest. It would be better if it required all symbols used in
splices to be exported.&lt;/p&gt;

&lt;p&gt;But it can be worked around. Just use trial and error to find every
Haskell library that does this, and then modify them to export
all the symbols they use. And after each one, rebuild all libraries
that depend on it.&lt;/p&gt;

&lt;p&gt;You're very unlikely to end up with more than 9 thousand lines of
patches. Because that's all it took me..&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The next problem (and the next one, and the next ...) is that
while GHC's code output by &lt;code&gt;-dump-splices&lt;/code&gt; (and indeed, by GHC
error messages, etc) looks like valid Haskell code to the casual viewer,
it's often not.&lt;/p&gt;

&lt;p&gt;To start with, it often has symbols qualified with the package
and module name. &lt;code&gt;ghc-prim:GHC.Types.:&lt;/code&gt; does not work well
where code originally contained &lt;code&gt;:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And then there's fun with multi-line strings, which sometimes
cannot be parsed back in by GHC in the form it outputs them.&lt;/p&gt;

&lt;p&gt;And then there's the strange way GHC outputs &lt;code&gt;case&lt;/code&gt; expressions,
which is not valid Haskell at all. (It's missing some semicolons.)&lt;/p&gt;

&lt;p&gt;Oh, and there's the lambda expressions that GHC outputs with insufficient
parentheses, leading to type errors at compile time.&lt;/p&gt;

&lt;p&gt;And so much more fun. Enough fun to give one the idea that this
GHC output has never really been treated as code that could be run again.
Because that would be a dumb thing to need to do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Just to keep things interesting, the Haskell libraries used by
your native GHC and your Android GHC need to be pretty much identical
versions. Maybe a little wiggle room, but any version skew could
cause unwanted results. Probably, most of the time, unwanted results
in the form of a 3 screen long type error message.&lt;/p&gt;

&lt;p&gt;(My longest GHC error message seen on this odyessy was actually
a full 500+ kilobytes in size. It included the complete text of
Jquery and Bootstrap. At times like these you notice that GHC outputs
its error messages o.n.e . c.h.a.r.a.c.t.e.r . a.t . a . t.i.m.e.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Anyway, if you struggle with it, or pay me vast quantities of money,
your program will, eventually, link. And that's all I can promise for now.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;PS, I hope nobody will ever find this blog post useful in their work.&lt;/p&gt;

&lt;p&gt;PPS, Also, if you let this put you off Haskell in any way .. well, don't.
You just might want to wait a year or so before doing Haskell on Android.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Wed, 3 Apr 2013 17:04:10 GMT</pubDate>
      <title>upstream git repositories</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=516</link>
      <guid>http://joeyh.name/blog/entry/upstream_git_repositories/</guid>
      <description>&lt;p&gt;Daniel Pocock posted
&lt;a href="http://danielpocock.com/autotools-project-distribution-and-packaging-on-debian" &gt;The multiple repository conundrum in Linux packaging&lt;/a&gt;.
While a generally good and useful post, which upstream developers
will find helpful to understand how Debian packages their software,
it contains this statement:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If it is the first download, the maintainer creates a new git
repository. If it has been packaged before, he clones the repository.
The important point here is that this is not the upstream repository,
it is an independent repository for Debian packaging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The only thing important about that point is that it highlights an
unnecessary disconnect between the Debian developer and upstream development.
One which upstream will surely find annoying and should certainly not
be bothered with.&lt;/p&gt;

&lt;p&gt;There is absolutely no technical reason to not use the upstream
git repository as the basis for the git repository used in Debian packaging.
I would never package software maintained in a git repository upstream
and not do so.&lt;/p&gt;

&lt;p&gt;The details are as follows:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;For historical reasons that are continuingly vanishing in importance,
Debian fetishises the tarballs produced by upstream. While upstreams
increasingly consider them an unimportant distraction, Debian insists
in hoarding and rolling around in on its nest of gleaming pristine tarballs.&lt;/p&gt;

&lt;p&gt;I wrote &lt;a href="http://joeyh.name/blog/../code/pristine-tar/" &gt;pristine-tar&lt;/a&gt; to facilitate this behavior, while
also pointing fun at it, and perhaps introducing a weak spot with which to
eventually slay this particular dragon. It is widely used within Debian.&lt;/p&gt;

&lt;p&gt;.. Anyway, the point is that it's no problem to import upstream's tarball
into a clone if their git repository. It's fine if that tarball includes
files not present in their git repository. Indeed, upstream can do this at
release time if they like. Or Debian developers can do it and push a small
quantity of data back to upstream in a branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sometimes tagged releases in upstream git repositories differ from
the files in their released tarballs. This is actually, in my experience,
less due to autotools generated files, and more due to manual and
imperfect release processes, human error, etc.
(Arguably, autotools are a form of human error.)&lt;/p&gt;

&lt;p&gt;When this happens, and the Debian developer is tracking upstream git,
they can quite easily modify their branch to reflect the contents of
the tarball as closely as they desire. Or modify the source package
uploaded to Debian to include anything left out of the tarball.&lt;/p&gt;

&lt;p&gt;My favorite example of this is an upstream who forgot to include
their README in their released tarball. Not a made up example; as mentioned
tarballs are increasingly an irrelevant side-show to upstreams. If
I had been treating the tarball as canonical I would have released a package
with no documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whenever Debian developers interact with upstream, whether it's by filing
bug reports or sending patches, they're going to be referring to refs in
the upstream git repository. They need to have that repository available.
The closer and better the relationship with upstream, the more
the DD will use that repository. Anything that pulls them away from
using that repository is going to add friction to dealing with upstream.&lt;/p&gt;

&lt;p&gt;There have, historically, been quite a lot of sources of friction.
From upstreams who choose one VCS while the DD preferred using another,
to DDs low on disk space who decided to only version control the
&lt;code&gt;debian&lt;/code&gt; directory, and not the upstream source code. With disk
space increasingly absurdly cheap, and the preponderance of development
converging on git, there's no reason for this friction to be allowed to
continue.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So using the upstream git repository is valuable.
And there is absolutely no technical value, and plenty of potential friction
in maintaining a history-disconnected git repository for Debian packaging.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Sat, 30 Mar 2013 17:04:11 GMT</pubDate>
      <title>Goodreads vs LibraryThing vs Free software</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=515</link>
      <guid>http://joeyh.name/blog/entry/Goodreads_vs_LibraryThing_vs_Free_software/</guid>
      <description>&lt;p&gt;Four years ago I &lt;a href="http://joeyh.name/blog/./entry/__34__whatcha_reading__63____34__/" &gt;started using Goodreads&lt;/a&gt; to maintain
the list of books I've read (which had lived in a flat text file for a
decade+ before that).&lt;/p&gt;

&lt;p&gt;Now it's been aquired by Amazon. I doubt it will survive in its current
form for more than 2 years. Anyway, while Goodreads has been a quite good
way to find what my friends are reading, I've been increasingly annoyed by
the quality of its recommendations, and its paucity of other features I
need. It really doesn't seem to help me keep up with new and interesting
fiction at all, unless my friends happen to read it.&lt;/p&gt;

&lt;p&gt;So I looked at LibraryThing. Actually, I seem to have looked at it several
times before, since it had accounts named "joey", "joeyh", and "joeyhess"
that were all mine. Which is what happens to me on sites that lack Openid
or Browserid.&lt;/p&gt;

&lt;p&gt;Digging a little deeper this time, I am finding its recommendations much
better than Goodreads' -- although it seems to sometimes recommend
books I've already read. And it has some nice features like tracking
series, so you can easily tell when you've read all the books in a series
or not. The analytics overall seem quite impressive. The UI is cluttered
and it seems to take 5 clicks to add and rate a single book. It supports
half stars.&lt;/p&gt;

&lt;p&gt;Overall I get the feeling this was designed for a set of needs that doesn't
quite match mine. For example, it seems it doesn't have a single database
entry per book; instead each time I add a book, it seems to pull in data
from primary sources (library of congress, Amazon &lt;em&gt;cough&lt;/em&gt;) and treat this
as a separate (but related) entry somehow. Weird. Perhaps this makes sense
to say, librarians. I'm willing to adjust how I think about things if
there's an underlying reason that can be grasped.&lt;/p&gt;

&lt;p&gt;There's a &lt;a href="http://www.librarything.com/topic/152033" &gt;quite interesting thread on LibraryThing&lt;/a&gt;
where the founder says:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Don't say we should open-source the code. That would be a nightmare! And
I have limited confidence in APIs. LibraryThing has the book geeks, but
not so much the computers geeks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I assume that the nightmare is that there would be dozens of clones of
the site, all balkanized, with no data transfer, no federation between
them.&lt;/p&gt;

&lt;p&gt;Except, that's the current situation, as every Goodreads user who is
now trying to use LibraryThing is discovering.&lt;/p&gt;

&lt;p&gt;Before I ever started using Goodreads, I &lt;a href="http://joeyh.name/blog/./entry/__34__whatcha_reading__63____34__/" &gt;made sure&lt;/a&gt;
it met my minimum criteria for putting my data into a proprietary silo:
That I could get the data back out. I can, and have. LibraryThing can
import it. But the import process loses data! And it's majorly clunky.
If I want to continue using Goodreads due to its better UI, and get the
data into LibraryThing, for its better analytics, I have to do
periodic dumps and loads of CSV files with manual fixups.&lt;/p&gt;

&lt;p&gt;This is why we have standards. This is why we're building federated social
networks like status.net and the upcoming pump.io that can pass structured
data between nodes transparently. It doesn't have to be a nightmare. It
doesn't have to rely on proprietary APIs. We have the computer geeks.&lt;/p&gt;

&lt;p&gt;Thing is, sites like GoodReads and LibraryThing need domain-specific
knowledge, and communities to curate data, and stuff like that. Things
that work well in a smallish company. (LibraryThing even has a business
model that makes sense, yearly payments to store more books in it.)&lt;/p&gt;

&lt;p&gt;With free software, it's much more appealing to sink the time we have into
the most general-purpose solution we can. Why build a LibraryThing when we
could build something that tracks not only books but movies and music? Why
build that when we could build a generic federated network for structured
social data? And that's great, as infrastructure, but if that
infrastructure is only used to build a succession of proprietary data
silos, what was the point?&lt;/p&gt;

&lt;p&gt;So, could some computer &amp;amp; book geeks please build a free software
alternative to these things, focused on books, that federates using any of
the fine APIs we have available? Bear in mind that there is already a nice
start at a comprehensive collection of book data in the
&lt;a href="http://openlibrary.org/" &gt;Open Library&lt;/a&gt;. I'd happily contribute to a crowd
funded project doing this.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 25 Mar 2013 02:04:14 GMT</pubDate>
      <title>difficulties in backing up live git repositories</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=514</link>
      <guid>http://joeyh.name/blog/entry/difficulties_in_backing_up_live_git_repositories/</guid>
      <description>&lt;blockquote&gt;
  &lt;p&gt;But you can&#x2019;t just tar.gz up the bare repositories on the server and hope
for the best. Maybe a given repository will be in a valid state; maybe it
won&#x2019;t.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-- Jeff Mitchell in &lt;a href="http://jefferai.org/2013/03/24/screw-the-mirrors/" &gt;a followup to the recent KDE near git disaster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a surprising statement to me. I seem to remember that one of
(many) selling points for git talked about back in the day was that it
avoided the problem that making a simple &lt;code&gt;cp&lt;/code&gt; (or backup) of a repository
could lead to an inconsistent result. A problem that subversion
repositories had, and required annoying commands to work around.
(&lt;code&gt;svnadmin $something&lt;/code&gt; -- iirc the backend FSFS fixed or avoided most of
this issue.)&lt;/p&gt;

&lt;p&gt;This prompted me to check how I handle it in
&lt;a href="http://ikiwiki-hosting.branchable.com" &gt;ikiwiki-hosting&lt;/a&gt;. I must have
anticipated a problem at some point, since &lt;code&gt;ikisite backup&lt;/code&gt; takes care
to lock the git repository in a way that prevents eg, incoming pushes
while a backup is running. Probably, like the KDE developers, I was
simply exercising reasonable caution.&lt;/p&gt;

&lt;p&gt;The following analysis has probably been written up before (train; limited
network availability; can't check), but here are some scenarios to consider:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;A non-bare repository has two parts that can clearly get out of sync
during a backup: The work tree and the &lt;code&gt;.git&lt;/code&gt; directory.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;The &lt;code&gt;.git&lt;/code&gt; directory will likely be backed up first,
since &lt;code&gt;getdirent&lt;/code&gt; will typically return it first, since it gets created
first . If a change is made
to the work tree during that backup, and committed while the work
tree is being backed up, the backup won't include that commit -- which
is no particular problem and would not be surprising upon restore.
Make commit again and get on with life.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;However, if (part of) the work tree is backed up before &lt;code&gt;.git&lt;/code&gt;, then
any changes that are committed to git during the backup would not be
reflected in the restored work tree, and &lt;code&gt;git diff&lt;/code&gt; would show a
reversion of those changes. After restore, care would need to be taken
to reset the work tree (without losing any legitimate uncommitted
changes).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A non-bare repository can also become broken in other ways if just
the wrong state is snapshotted. For example, if a commit is in progress
during a backup, &lt;code&gt;.git/index.lock&lt;/code&gt; may exist, and prevent future commits
from happening, until it's deleted. These problems can also occur
if the machine dies at just the right time during a commit. Git tells
you how to recover. (git
could go further to avoid these problems than it does; for example
it could check if &lt;code&gt;.git/index.lock&lt;/code&gt; is actually locked using fcntl.
Something I do in &lt;a href="http://joeyh.name/blog/../code/git-annex/" &gt;git-annex&lt;/a&gt; to make the &lt;code&gt;.git/annex/index.lock&lt;/code&gt;
file crash safe.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A bare repository could be receiving a push (or a non-bare repository
a pull) while the backup occurs. These are fairly similar cases,
with the main difference being that a non-bare repository has the reflog,
which can be used to recover from some inconsist states that could be
backed up. Let's concentrate on pushes to bare repositories.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;A pack could be in the process of being uploaded during a backup.
The KDE developers apparently worried that this could result in
a corrupt or inconsistent repository, but TTBOMK it cannot;
git transfers the pack to a temp file and atomically renames it into
place once the transfer is complete. A backup may include an excess
temp file, but this can also happen if the system goes down
while a push is in progress. Git cleans these things up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A push first transfers the &lt;code&gt;.git/objects&lt;/code&gt;, and then updates &lt;code&gt;.git/refs&lt;/code&gt;.
A backup might first back up the refs, and then the objects. In this
case, it would lose the record that refs were pushed. After being
restored, any push from another repository would update the refs,
even using the objects that did get backed up. So git recovers from
this, and it's not really a concern.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perhaps a backup chooses to first back up the objects, and then the
refs. In this case, it could back up a newly changed ref, without
having backed up the referenced objects (because they arrived
after the backup had finished with the objects). When this happens,
your bare repository is inconsistent; you have to somehow hunt down
the correct ref for the objects you do have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a bad failure mode.&lt;/strong&gt; git could improve this, perhaps, by
maintaining a reflog for bare repositories, which, in my limited
testing, it does not do.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A "backup" of a git repository can consist of other clones of it.
Which do not include &lt;code&gt;.git/hooks/&lt;/code&gt; scripts, &lt;code&gt;.git/config&lt;/code&gt; settings,
and potentially other valuable information, that strangely, we do not
check into revision control despite having this nice revision control
system available. This is the most likely failure mode with "git backups".
:P&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I think that it's important git support naive backups of git repositories
as well as possible, because that's probably how most backups of git
repositories are made. We don't all have time to carefully tune our
backup systems to do something special around our git repositories to
ensure we get them in a consistent state like the KDE project did, and as
their experience shows, even if we do it, we can easily introduce other,
unanticipated problems.&lt;/p&gt;

&lt;p&gt;Can anyone else think of any other failure modes like these, or
find holes in my slightly rushed analysis?&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;PS: &lt;a href="http://joeyh.name/blog/../code/git-annex/" &gt;git-annex&lt;/a&gt; is itself entirely crash-safe, to the best of my
abilities, and also safe for naive backups. But inherits any
problems with naive backups of git repositories.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 21 Feb 2013 01:04:10 GMT</pubDate>
      <title>Kickstarter rewards wrap-up</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=513</link>
      <guid>http://joeyh.name/blog/entry/Kickstarter_rewards_wrap-up/</guid>
      <description>&lt;p&gt;I finished delivering all my
&lt;a href="http://joeyh.name/blog/./entry/kickstarter_for_git-annex_assistant/" &gt;Kickstarter&lt;/a&gt; rewards at the end of
the year. This is an overview of how that went, both financially and in
general.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;my Kickstarter pie (not including taxes)&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/kickstarter/moneypie.png" &gt;
        &lt;img src="http://joeyh.name/blog/./pics/kickstarter/moneypie.png" width="426" height="311" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;While the Kickstarter was under way, several friends warned me that I might
end up spending a lot of the money for rewards, or even shipping, and come
out a loser. It's happened to some people, but I avoided it. Most of the
pie went to its intended purpose.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;USB key arrives in Amsterdam&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/kickstarter/keyletteramsterdam.jpeg" &gt;
        &lt;img src="http://joeyh.name/blog/./pics/kickstarter/keyletteramsterdam.jpeg" width="640" height="480" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;I kept shipping cost low by shipping everything by US postal service,
including Air Mail for international shipping. This was particularly
important for the stickers (which cost $1.05 to ship internationally).
But I also shipped USB keys in regular mail envelopes, protected by bubble
wrap, which worked very well and avoided the bother of shipping packages.
The USPS will be annoyed at you for a rigid letter and add a non-machinable
surcharge, but it's still a nice savings.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;expenses&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/kickstarter/expenses.png" &gt;
        &lt;img src="http://joeyh.name/blog/./pics/kickstarter/expenses.png" width="390" height="310" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;I spent more on rewards than on transaction fees, but the fees are still
pretty large. Being dinged a second time by Amazon is the worst part. I
have not been able to work out exactly what formula Kickstarter uses to
determine its fee per pledge. It does not seem to be a simple percentage of
the pledge. For example, they seem to have charged $0.25 per $10 pledge,
but $25 for a $500 pledge. I wanted to solve this, but I'd have to match up
all the pledges and fees manually to do it.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;gross income by reward type&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/kickstarter/rewardpie.png" &gt;
        &lt;img src="http://joeyh.name/blog/./pics/kickstarter/rewardpie.png" width="419" height="285" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;This chart is slightly innacurrate, because it puts any money pledged,
beyond the amount needed to get a reward, into the "intangibles" category,
despite the reward being probably responsible for that money being pledged.&lt;/p&gt;

&lt;p&gt;(The intangibles also includes people who did not ask for a reward, and
several categories of rewards not involving shipping matter around.)&lt;/p&gt;

&lt;p&gt;But, the surprise for me is how large a peice the T-shirts are responsible
for. It was my least favorite reward, and a low volume one, but I made out
pretty well on it. However, I'd still try to avoid putting T-shirts on
Kickstarter again. It's hard to do a good design (I didn't, really);
they're expensive, and were by far the most annoying thing to ship. Also, I
was not happy with the countries Cafe Press sourced their shirts from; I've
been to Honduras and talked with people who have relatives in las machinas.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;gross and net income by
reward type (excluding shipping)&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/kickstarter/rewardbar.png" &gt;
        &lt;img src="http://joeyh.name/blog/./pics/kickstarter/rewardbar.png" width="334" height="257" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;In contrast, the stickers had an amazing margin; they're so inexpensive
to print that I printed up two kinds and included multiple with every other
reward I mailed. I still have hundreds left over, too.. All the online
print shops I tried have very annoying interfaces to upload artwork though.
I had to do quite a bit of math to render TIFF files with appropriate DPI
and margins.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="http://joeyh.name/blog/./pics/kickstarter/keyarrived.jpg" &gt;
    &lt;img src="http://joeyh.name/blog/./pics/kickstarter/keyarrived.jpg" width="552" height="513" class="img"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;The USB keys were my favorite reward. I got them from
&lt;a href="http://www.usbmemorydirect.com/" &gt;USB Memory Direct&lt;/a&gt;, who gave me quite a
nice deal. I was very happy that I was able to send them a SVG file
of my artwork, so I didn't need to worry about lacking resolution for the
laser engraving. And it came out looking great.&lt;/p&gt;

&lt;p&gt;The best part was when their sales guy Mike actually did a minor alteration
of the artwork, to better fit on the key, when I, being overloaded with
Kickstarter stuff asked him too. A bit above and beyond.&lt;/p&gt;

&lt;p&gt;There was an issue with their Chinese manufacturer's quality control of the
16 gb drives, but they were willing to send me replacement for all the ones
I found problems with.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;All told I spent probably 3 full days stuffing and shipping envelopes,
and probably spent a week working on Kickstarter reward fullfillment.
As work-related overhead goes, that's not bad. Maybe someone considering a
Kickstarter will find this information useful somehow. Oh well, back to
&lt;a href="http://git-annex.branchable.com/design/assistant/blog" &gt;work&lt;/a&gt;. :)&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 7 Feb 2013 17:05:04 GMT</pubDate>
      <title>Sydney nostalgia</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=512</link>
      <guid>http://joeyh.name/blog/entry/Sydney_nostalgia/</guid>
      <description>&lt;p&gt;
  &lt;a href="http://joeyh.name/blog/./pics/operahouse.jpg" &gt;
    &lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/x350-operahouse.jpg" width="630" height="350" alt="Sydney opera house viewed from a ferry" class="img"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Last Saturday, when the bus from Canberra pulled into Sydney's central
station, I found myself feeling curiously nostalgic for this city, and
particularly this bustling and somewhat seedy[1] neighborhood of Haymarket
and Redfern.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="http://joeyh.name/blog/./pics/kimberlane.jpg" &gt;
    &lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/x400-kimberlane.jpg" width="300" height="400" alt="glowing angels in Kimber lane" class="img"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I only spent 5 days in Sydney, but living in a shared house there, walking
up to Central every day, and returning to the outskirts of the Haymarket
every evening to slurp noodles or other asian food, I got into a routine.
And got a sense of the place that goes perhaps a bit beyond the tourist
sights.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="http://joeyh.name/blog/./pics/manlypano.jpg" &gt;
    &lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/1024x-manlypano.jpg" width="1024" height="200" alt="Manly beach panorama" class="img"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Perhaps if I'd had more time I would have found a decent coffee shop
that had both free wifi and abundant seating. They seem scarce in Sydney.
I instead often got on the ferry to Manly when I wanted some sit down and
code time.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://joeyh.name/blog/./pics/cliffside.jpg" &gt;&lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/300x-cliffside.jpg" width="300" height="225" alt="Cliffside" class="img"/&gt;&lt;/a&gt;
&lt;a href="http://joeyh.name/blog/./pics/protectdragons.jpg" &gt;&lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/300x-protectdragons.jpg" width="300" height="202" alt="Protect Our Water Dragons sign" class="img"/&gt;&lt;/a&gt;&lt;br/&gt;
One time when I was exploring the headlands above Manly beach, I noticed
this sign.&lt;br/&gt;
Then I ran into this guy. Click him for an amusing video.&lt;br/&gt;&lt;a href="http://downloads.kitenet.net/videos/dragon.ogv" &gt;&lt;img src="http://joeyh.name/blog/./entry/Sydney_nostalgia/300x-waterdragon.jpg" width="300" height="176" alt="lizard" class="img"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway, Sydney is on my very short list of cities I'd actually enjoy spending
some more time in some day, along with San Francisco, Vancouver, Oslo, and
London.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;[1] Depending on what's inside all the "VIP lounges" and "Thai massage
parlours" on every corner that I did not explore, perhaps thoroughly seedy?&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Tue, 5 Feb 2013 04:04:08 GMT</pubDate>
      <title>LCA2013 wrapup</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=511</link>
      <guid>http://joeyh.name/blog/entry/LCA2013_wrapup/</guid>
      <description>&lt;p&gt;After 27 hours of travel, I'm finally back from my
first &lt;a href="http://linux.conf.au/" &gt;Linux.conf.au&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This was a great conference! Some of my favorite highlights:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Out for dinner the first night, my whole table started spontaneously
talking about Haskell, including details of IO management frameworks
like conduit and pipes, and a new one that's waiting in the wings.
That just doesn't happen in the real world. A lot of us continued to
do Haskell stuff in the hallway track, although for some reason there
were no Haskell talks on the official schedule. Maybe it's time for a
Haskell miniconf at LCA?&lt;/li&gt;
&lt;li&gt;Meeting Josh, Jamie, Sarah, Brendan, Craig, and others I've worked with
online but never encountered IRL. Also reconnecting with old friends
(some I'd not seen in 13 years) and finding new ones.&lt;/li&gt;
&lt;li&gt;The speaker's dinner in a revolving restaurant overlooking Canberra.
Leave it to a restaurant full of geeks to invent an asychronous communications
medium in such a setting. (Notes attached to windows to be read and
answered by tables as they rotated by.)&lt;/li&gt;
&lt;li&gt;Meeting quite a lot of git-annex users, Kickstarter backers, and
people interested in using git-annex. Thanks to everyone who came up
to me for a chat.&lt;/li&gt;
&lt;li&gt;The evening pickup board game sessions. Especially my wiping out three
other Tsuro players at once by forcing them all to end on the same square. ;)
These were where I felt the most at home in Australia.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Robert_Llewellyn" &gt;Robert Llewellyn&lt;/a&gt; dropping
in and mingling with fans of Red Dwarf and Scrapheap Challenge. One of the
very few actors I could possibly fanboy on, and LCA not only somehow got
him, but constructed an atmosphere that allowed for this photo of us.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
  &lt;a href="http://joeyh.name/blog/./pics/with_Llewellyn.jpg" &gt;
    &lt;img src="http://joeyh.name/blog/./entry/LCA2013_wrapup/320x-with_Llewellyn.jpg" width="320" height="240" class="img"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4" &gt;My git-annex talk&lt;/a&gt;
went ok, despite technical problems with the video output, which the video
team did a great job of working around. The first demo went well, and the Q&amp;amp;A
was excellent.&lt;/p&gt;

&lt;p&gt;The demo of the git-annex assistant webapp was marred by, apparently, a
bad build of the webapp -- which I ironically used rather than my usual
development build because I assumed it'd be less likely to fail. At least I
may have a way to reproduce that hang somewhat reliably now, so I can get
on with debugging it. I will be redoing a demo of the webapp as a screencast.&lt;/p&gt;

&lt;hr/&gt;&lt;p&gt;Here are some of the best talks I attended. (I have quite a lot more queued
up to watch still, and had to cut several due to space.)
Click titles for videos, or &lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/" &gt;browse all the videos&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Git_For_Ages_4_And_Up.mp4" &gt;Git for Ages 4 and Up&lt;/a&gt;&lt;br/&gt;
Schwern has found a new, excellent way to explain git. I felt rather
bad for using up a seat, especially once people were kicked out
when the room was filled over capacity. But I enjoyed every minute of it.
(Also has the best speaker intro ever. "Schwern once typed &lt;code&gt;git pull --hard&lt;/code&gt;
and pulled GitHub's sever room across the street.")&lt;/p&gt;

&lt;p/&gt;&lt;table&gt;&lt;caption&gt;  BTW, I must confess: I left the red apple on teacher's desk.
&lt;/caption&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://joeyh.name/blog/./pics/git4up.png" &gt;&lt;img src="http://joeyh.name/blog/./entry/LCA2013_wrapup/320x-git4up.png" width="320" height="240" class="img"/&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Keynote_Radia_Perlman.mp4" &gt;Radia Perlman's keynote&lt;/a&gt;&lt;br/&gt;
Network protocol design and poetry from one of the quiet heros of
our field. I knew Spanning Tree Protocol was used in ethernet,
but it just works, so like many I never paid much attention to it.
This talk felt like the best lectures, where you're learning from a master
on multiple levels at once.
Well done work often becomes an unremarked part of the landscape,
which I sometimes find unrewarding, so it was great to have Radia give
some perspective on what that's like over the course of decades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Conference_Closing_Lightning_Talks.mp4" &gt;Lightning Talks&lt;/a&gt;&lt;br/&gt;
A 90 second time limit really helps. Too many conferences have 5 minute
talks, which is less exciting. If you still find them boring,
skip forward to 13:50, where &lt;a href="http://twitter.com/pjf" &gt;pjf&lt;/a&gt;
does two talks in 90 seconds! (If a 20 second talk on depression
is too .. manic, there's an encore at the end.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/The_IPocalypse_20_months_later.mp4" &gt;The IPocalypse 20 months later&lt;/a&gt;&lt;br/&gt;
A reality check, with real data. Very important stuff here.
We need to work to avoid this worst case scenario, and we also need to design
around it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/REPENT_FOR_THE_END_OF_THE_UNIX_EPOCH_IS_NIGH.mp4" &gt;REPENT!!! FOR THE END OF THE UNIX EPOCH IS NIGH!!!&lt;/a&gt;&lt;br/&gt;
Wildest talk beginning I've seen since RMS put the hard drive halo on his
head. And to an important point: Any programs that deal with dates 25 years
in the future already need to be fixed today to deal with the epoch rollover.
This got me digging around in Haskell date libraries, to make sure they're
ok.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Building_Persona_federated_and_privacysensitive_identity_for_the_Web.mp4" &gt;Building Persona: Federated and Privacy Sensitive Identity for the Web&lt;/a&gt;&lt;br/&gt;
This talk and some previous conversation with Francois have convinced
me that Persona (AKA Browserid) has a design that can succeed.
I will be adding Persona login support to ikiwiki.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Beyond_Alt_Text_What_Every_Project_Should_Know_About_Accessibility.mp4" &gt;Beyond Alt Text: What Every Project Should Know About Accessibility&lt;/a&gt;&lt;br/&gt;
I missed the first half due to giving my talk, but the second half
was full of rather a lot of excellent information, some of which I'd
only guessed at before.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/Git_not_just_for_source_code_anymore.mp4" &gt;Git: Not Just for Source Code Anymore&lt;/a&gt;&lt;br/&gt;
Good overview of the new ways to use git. Also kept giving examples from
my body of work, which is some nice ego stroking, thanks Josh. ;-)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <pubDate>Wed, 23 Jan 2013 07:41:47 GMT</pubDate>
      <title>in Sydney</title>
      <link>http://www.advogato.org/person/joey/diary.html?start=510</link>
      <guid>http://joeyh.name/blog/entry/in_Sydney/</guid>
      <description>&lt;p&gt;After arriving yesterday, and doing the obligatory jetlagged wander around
&lt;a href="http://en.wikipedia.org/wiki/Circular_Quay" &gt;Circular Quay&lt;/a&gt; to the
Opera House, I crashed for 15 hours sleep and seem reasonably well over the
jetlag now. I'm staying near Central Station, which is great because it's
very convenient to transport and there's lots of cheap ethnic food.&lt;/p&gt;

&lt;table&gt;&lt;caption&gt;view down my street&lt;/caption&gt;
  &lt;tr&gt;&lt;td&gt;
      &lt;a href="http://joeyh.name/blog/./pics/chalmersst.jpg" &gt;
        &lt;img src="http://joeyh.name/blog/./entry/in_Sydney/640x-chalmersst.jpg" width="640" height="426" class="img"/&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Today I took the ferry over to &lt;a href="http://en.wikipedia.org/wiki/Manly_beach" &gt;Manly Beach&lt;/a&gt;.
I had to get in some in swimming of course, although today was cloudy and only
in the 80's (F). That was ok, but the really nice bit was walking over to
&lt;a href="http://bit.ly/ijHVQR" &gt;Shelly Beach&lt;/a&gt;
and up along the sandstone cliffs near
&lt;a href="http://en.wikipedia.org/wiki/Sydney_Heads" &gt;North Head&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Highlight was finding a small gotto high on the cliff,
with some beautiful sandstone filigree overhead,
that seemed carved by water (but probably really by wind), and
contained a shady bench overlooking the Pacific.
Great place to enjoy a lunch of crusty bread and salami if you're
ever in the area.&lt;/p&gt;

&lt;p&gt;Topped off a great day with a random trip to
&lt;a href="http://en.wikipedia.org/wiki/Neutral_Bay" &gt;Neutral Bay&lt;/a&gt;
(the D&amp;amp;Der in me liked the name, and why not, ferries are free) and
a wander through the
&lt;a href="http://en.wikipedia.org/wiki/Royal_Botanical_Gardens,_Sydney" &gt;Royal Botanic Gardens&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm hoping to spend either Thursday or Friday at a co-working or hackerspace
in Sydney, but I don't know where yet. Any locals have ideas?&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
