<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>numerodix blog &#187; technology</title>
	<atom:link href="http://www.matusiak.eu/numerodix/blog/index.php/category/techno-babble/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.matusiak.eu/numerodix/blog</link>
	<description>A blog about nothing</description>
	<lastBuildDate>Sun, 12 Feb 2012 12:20:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>re: for the man with many repos</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2011/11/13/re-for-the-man-with-many-repos/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2011/11/13/re-for-the-man-with-many-repos/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 14:21:30 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=3323</guid>
		<description><![CDATA[As it often goes, re is a tool that grew out of a bunch of shell scripts. I kept adding stuff to the scripts for a long time, but eventually it went beyond the point of being manageable.
The tool addresses three different issues:

Cloning/pulling multiple repos in one step.
Keeping repo clones in sync across machines.
Better handling [...]]]></description>
			<content:encoded><![CDATA[<p>As it often goes, <code>re</code> is a tool that grew out of a bunch of shell scripts. I kept adding stuff to the scripts for a long time, but eventually it went beyond the point of being manageable.</p>
<p>The tool addresses three different issues:</p>
<ul>
<li>Cloning/pulling multiple repos in one step.</li>
<li>Keeping repo clones in sync across machines.</li>
<li>Better handling of local tracking branches.</li>
</ul>
<h3>Listing repos</h3>
<p>Let&#8217;s start with a basic situation. I&#8217;ve cloned some of my repos on github:</p>
<pre class="bash">$ ls -F
galleryforge/  italian-course/  re/  spiderfetch/</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/re_ls_repos.txt">re_ls_repos.txt</a></p>
<p>I run <code>re list</code> to scan the current path recursively and discover all the repos that exist:</p>
<pre class="bash">$ re list
<span style="color: #66cc66;">&#91;</span>galleryforge:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/galleryforge.git
<span style="color: #66cc66;">&#91;</span>italian-course:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/italian-course.git
<span style="color: #66cc66;">&#91;</span>re:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/re.git
<span style="color: #66cc66;">&#91;</span>spiderfetch:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/spiderfetch.git
&gt; Run with -u to update .reconfig</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/re_list.txt">re_list.txt</a></p>
<p>It creates a configuration file called <code>.reconfig</code> that contains the output you see there. By default it doesn&#8217;t overwrite the config, just shows you the result of the detection action. Pass <code>-u</code> to update it.</p>
<p>This file format is similar to <code>.git/config</code>. Every block is a repo, and <code>:git</code> is a tag saying &#8220;this is a git repo&#8221;. (By design <code>re</code> is vcs agnostic, but in practice I only ever use git and the only backend right now is for git. It probably smells a lot of git in any case.)</p>
<p>Every line inside a block represents a remote (git terminology). By default there is only one. If you add add a remote in the repo and re-run <code>re list</code> it will detect it. But it will assume that <code>origin</code> is the canonical remote (more on why this matters later).</p>
<h3>Pulling repos</h3>
<p>Now let&#8217;s say I want to pull all those repos to sync them with github. I use (you guessed it) <code>re pull</code>:</p>
<pre class="bash">$ re pull
&gt; Fetching galleryforge
&gt; Fetching italian-course
&gt; Fetching re
&gt; Fetching spiderfetch
&gt; Merging galleryforge
&gt; Merging italian-course
&gt; Merging re
&gt; Merging spiderfetch
-&gt; Setting up <span style="color: #000066;">local</span> tracking branch ruby-legacy
-&gt; Setting up <span style="color: #000066;">local</span> tracking branch sqlite-try
-&gt; Setting up <span style="color: #000066;">local</span> tracking branch db-subclass
-&gt; Setting up <span style="color: #000066;">local</span> tracking branch next</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/re_pull.txt">re_pull.txt</a></p>
<p>As you can see it does fetching and merging in separate steps. Fetching is where all the network traffic happens, merging is local, which is why I think it&#8217;s nice to separate them. (But there are <a href="http://longair.net/blog/2009/04/16/git-fetch-and-merge/">more reasons to avoid git pull</a>.)</p>
<p>What it also does is set up local tracking branches against the canonical remote. The canonical remote is the one listed <em>first</em> in <code>.reconfig</code>. So it doesn&#8217;t matter what it&#8217;s called, but it&#8217;s a good idea to make it <code>origin</code>, because that&#8217;s what <code>re list</code> will assume when you use it to update <code>.reconfig</code> after you add/remove repos.</p>
<p>It handles local tracking branches only against one remote, because if both <code>origin</code> and <code>sourceforge</code> have a branch called <code>stable</code> then it&#8217;s not clear which one of those the local branch <code>stable</code> is supposed to track. I find this convention quite handy, but your mileage may vary.</p>
<p>If I later remove the branch <code>ruby-legacy</code> from github and run <code>re pull</code>, it&#8217;s going to detect that I have a local tracking branch that is pointing at something that doesn&#8217;t exist anymore:</p>
<pre class="bash">$ re pull spiderfetch
&gt; Fetching spiderfetch
&gt; Merging spiderfetch
-&gt; Stale <span style="color: #000066;">local</span> tracking branch ruby-legacy, remove? <span style="color: #66cc66;">&#91;</span>yN<span style="color: #66cc66;">&#93;</span></pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/re_pull_stale_local_tracking.txt">re_pull_stale_local_tracking.txt</a></p>
<h3>Scaling beyond a single machine</h3>
<p>Now, <code>re</code> helps you manage multiple repos, but it also helps you keep your repos synced across machines. <code>.reconfig</code> is a kind of spec for what you want your repo-hosting directory to contain, so you can just ship it to a different machine, <code>re pull</code> and it will clone all the repos over there, set up local tracking branches, all the same stuff.</p>
<p>In fact, why not keep <code>.reconfig</code> <em>itself</em> in a repo, which again you can push to a central location and from which you can pull onto all your machines:</p>
<pre class="bash">$ re list
<span style="color: #66cc66;">&#91;</span>.:git<span style="color: #66cc66;">&#93;</span>
    origin.url = user@host:~/repohost.git
<span style="color: #66cc66;">&#91;</span>galleryforge:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/galleryforge.git
<span style="color: #66cc66;">&#91;</span>italian-course:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/italian-course.git
<span style="color: #66cc66;">&#91;</span>re:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/re.git
<span style="color: #66cc66;">&#91;</span>spiderfetch:git<span style="color: #66cc66;">&#93;</span>
    origin.url = git@github.com:numerodix/spiderfetch.git
&gt; Run with -u to update .reconfig</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/re_list_reconfig.txt">re_list_reconfig.txt</a></p>
<p>It does not manage <code>.gitignore</code>, so you have to do that yourself.</p>
<h3>Advanced uses</h3>
<p>Those are the basics of <code>re</code>, but the thing to realize is that it doesn&#8217;t limit you to a situation like the one we&#8217;ve seen in the examples so far, with a single directory that contains repos. You can have repos at any level of depth, you can have <code>.reconfig</code>s at different levels too, and you can then use a single <code>re pull -r</code> to recursively pull absolutely everything in one step.</p>
<p>Get it from github:</p>
<ul>
<li><a href="https://github.com/numerodix/re">re</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2011/11/13/re-for-the-man-with-many-repos/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>full system encryption</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2011/06/02/full-system-encryption/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2011/06/02/full-system-encryption/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 18:35:04 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=3266</guid>
		<description><![CDATA[In the age of laptops I was thinking maybe it&#8217;s time I finally try encrypting my disk. I&#8217;ve never done it before, so before going for it I needed a small approfondimento.
The common strategy seems to be roughly:

Leave /boot unencrypted.
Encrypt the rest of the disk with LUKS. You then have dm-crypt that provides a mapping [...]]]></description>
			<content:encoded><![CDATA[<p>In the age of laptops I was thinking maybe it&#8217;s time I finally try encrypting my disk. I&#8217;ve never done it before, so before going for it I needed a small approfondimento.</p>
<p>The common strategy seems to be roughly:</p>
<ol>
<li>Leave <code>/boot</code> unencrypted.</li>
<li>Encrypt the rest of the disk with <a href="http://code.google.com/p/cryptsetup/">LUKS</a>. You then have <code>dm-crypt</code> that provides a mapping between the partition (according to the partition table) and the corresponding unencrypted block device, which becomes a node like <code>/dev/mapper/nodename</code>, depending on what you call it.</li>
<li>Use <code>/dev/mapper/nodename</code> as the &#8220;physical&#8221; partition which you assign to lvm and make into a volume group.</li>
<li>Create logical volumes in the volume group, so that each logical volume corresponds to what we used to call a partition on the old model, ie. <code>/</code>, <code>/home</code>, <code>/var</code> etc.</li>
</ol>
<p>lvm is practical here, because you need at least two partitions, / and swap.  You could just as well create multiple partitions sda5,sda6,&#8230; and encrypt each one, but then you&#8217;d have to unlock them individually on boot, which is hacky.</p>
<p>The setup is a bit involved and I would rather be spared the trouble of doing it manually. The ubuntu alternate install cd has a fully automatic feature that does this, using the whole disk. If you&#8217;re happy with the basic scheme, but you want more partitions or you want to size them differently, you can use the curses gui following a nice guide like <a href="http://joernfranz.net/2011/01/20/installing-ubuntu-10-10-with-full-disk-encryption/">this one</a>.</p>
<p>So far so good, but now comes the inevitable question. Much like with compression you want to be able to not only compress but also to decompress. What if I screw up my boot sector or my fstab and I need to boot from a rescue cd? How do I mount <code>/dev/sda5</code> now?</p>
<h3>Mounting manually</h3>
<p>First of all, in case we don&#8217;t have all the tools we need:</p>
<pre class="bash">$ apt-get install lvm2
$ modprobe dm-mod</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-prereq.sh">rescue-encrypted_fs-prereq.sh</a></p>
<p>We obviously need to know what the physical partitions actually are:</p>
<pre class="bash">$ fdisk -l /dev/sda
&nbsp;
Disk /dev/sda: <span style="color: #cc66cc;">32</span>.<span style="color: #cc66cc;">2</span> GB, <span style="color: #cc66cc;">32212254720</span> bytes
<span style="color: #cc66cc;">255</span> heads, <span style="color: #cc66cc;">63</span> sectors/track, <span style="color: #cc66cc;">3916</span> cylinders
Units = cylinders of <span style="color: #cc66cc;">16065</span> * <span style="color: #cc66cc;">512</span> = <span style="color: #cc66cc;">8225280</span> bytes
Sector size <span style="color: #66cc66;">&#40;</span>logical/physical<span style="color: #66cc66;">&#41;</span>: <span style="color: #cc66cc;">512</span> bytes / <span style="color: #cc66cc;">512</span> bytes
I/O size <span style="color: #66cc66;">&#40;</span>minimum/optimal<span style="color: #66cc66;">&#41;</span>: <span style="color: #cc66cc;">512</span> bytes / <span style="color: #cc66cc;">512</span> bytes
Disk identifier: 0x000a30a5
&nbsp;
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           <span style="color: #cc66cc;">1</span>          <span style="color: #cc66cc;">13</span>       <span style="color: #cc66cc;">96256</span>   <span style="color: #cc66cc;">83</span>  Linux
Partition <span style="color: #cc66cc;">1</span> does not end on cylinder boundary.
/dev/sda2              <span style="color: #cc66cc;">13</span>        <span style="color: #cc66cc;">3917</span>    <span style="color: #cc66cc;">31357953</span>    <span style="color: #cc66cc;">5</span>  Extended
/dev/sda5              <span style="color: #cc66cc;">13</span>        <span style="color: #cc66cc;">3917</span>    <span style="color: #cc66cc;">31357952</span>   <span style="color: #cc66cc;">83</span>  Linux</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-fdisk.sh">rescue-encrypted_fs-fdisk.sh</a></p>
<p><code>/dev/sda1</code> is <code>/boot</code>, that&#8217;s easy. Then we have <code>/dev/sda5</code>, which is the encrypted partition and mounting it directly will not work. This is where <code>dm-crypt</code> comes into the picture: we are going to unlock the partition, obtaining a block device that represents the unencrypted view of the partition.</p>
<pre class="bash">$ cryptsetup luksOpen /dev/sda5 vg0
$ <span style="color: #000066;">cd</span> /dev/mapper
$ ls -lh
crw-------    <span style="color: #cc66cc;">1</span> root     root       <span style="color: #cc66cc;">10</span>, <span style="color: #cc66cc;">236</span> Jun  <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">16</span>:<span style="color: #cc66cc;">44</span> control
lrwxrwxrwx    <span style="color: #cc66cc;">1</span> root     root           <span style="color: #cc66cc;">7</span> Jun  <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">16</span>:<span style="color: #cc66cc;">47</span> vg0 -&gt; ../dm<span style="color: #cc66cc;">-0</span></pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-cryptsetup.sh">rescue-encrypted_fs-cryptsetup.sh</a></p>
<p>We have decided to call the block device <code>vg0</code>, and it thus appears as <code>/dev/mapper/vg0</code>. Since we know this is an lvm volume group we use the lvm tools to figure out what it contains:</p>
<pre class="bash">$ vgscan
  Reading all physical volumes.  This may take a <span style="color: #b1b100;">while</span>...
  Found volume group <span style="color: #ff0000;">"vg0"</span> using metadata <span style="color: #000066;">type</span> lvm2
$ vgs
  VG   <span style="color: #808080; font-style: italic;">#PV #LV #SN Attr   VSize  VFree</span>
  vg0    <span style="color: #cc66cc;">1</span>   <span style="color: #cc66cc;">2</span>   <span style="color: #cc66cc;">0</span> wz--n- <span style="color: #cc66cc;">29</span>.90g    <span style="color: #cc66cc;">0</span>
$ lvscan
  inactive          <span style="color: #ff0000;">'/dev/vg0/swap'</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span>.<span style="color: #cc66cc;">86</span> GiB<span style="color: #66cc66;">&#93;</span> inherit
  inactive          <span style="color: #ff0000;">'/dev/vg0/root'</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">28</span>.<span style="color: #cc66cc;">04</span> GiB<span style="color: #66cc66;">&#93;</span> inherit</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-lvm-vscan.sh">rescue-encrypted_fs-lvm-vscan.sh</a></p>
<p>We have two logical volumes in there. But they are inactive, which means they are not visible under <code>/dev</code>, ie. we can&#8217;t mount them. To make them active:</p>
<pre class="bash">$ vgchange -a y
  <span style="color: #cc66cc;">2</span> logical volume<span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">in</span> volume group <span style="color: #ff0000;">"vg0"</span> now active</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-lvm-activate.sh">rescue-encrypted_fs-lvm-activate.sh</a></p>
<p>The device names listed before are now visible and we can mount them:</p>
<pre class="bash">$ <span style="color: #000066;">cd</span> /dev/vg0
$ ls -lh
lrwxrwxrwx <span style="color: #cc66cc;">1</span> root root <span style="color: #cc66cc;">7</span> Jun  <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">18</span>:<span style="color: #cc66cc;">24</span> root -&gt; ../dm<span style="color: #cc66cc;">-2</span>
lrwxrwxrwx <span style="color: #cc66cc;">1</span> root root <span style="color: #cc66cc;">7</span> Jun  <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">18</span>:<span style="color: #cc66cc;">24</span> swap -&gt; ../dm<span style="color: #cc66cc;">-1</span>
$ swapon /dev/vg0/swap
$ mount /dev/vg0/root /mnt</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/rescue-encrypted_fs-mount.sh">rescue-encrypted_fs-mount.sh</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2011/06/02/full-system-encryption/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ironpython + gtk</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2011/04/09/ironpython-gtk/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2011/04/09/ironpython-gtk/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 13:57:26 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[reviews]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=3226</guid>
		<description><![CDATA[ I develop a bunch of tools for my own use that usually run in the terminal, for the simple reason that this maximizes their usability to me. It&#8217;s also true that usually a terminal program takes much less code and effort to write than a gui program.
But occasionally I want to make something of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nametrans.sourceforge.net/"><img class="alignright size-full wp-image-3227" title="nametrans_about_box" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_about_box.png" alt="nametrans_about_box" width="304" height="210" /></a> I develop a bunch of tools for my own use that usually run in the terminal, for the simple reason that this maximizes their usability to me. It&#8217;s also true that usually <a href="http://www.matusiak.eu/numerodix/blog/index.php/2011/03/25/nametrans-renaming-with-search-replace/">a terminal program</a> takes much less code and effort to write than a gui program.</p>
<p>But occasionally I want to make something of mine usable to the so-called &#8220;end users&#8221; that we keep hearing about. So what I was wondering about was: <strong>What would it be like to add a gui to an existing python program and run it on .NET?</strong></p>
<p>How do you find out? You <a href="http://nametrans.sourceforge.net/">try it</a>. This is something that I&#8217;ve been meaning to try for a while anyway.</p>
<p>Pros:</p>
<ul>
<li>2.3mb download</li>
</ul>
<p>Cons:</p>
<ul>
<li>gtk# dependency</li>
<li>sluggish gui</li>
</ul>
<h3>Gtk</h3>
<p>This is the first time I&#8217;ve used gtk. I&#8217;ve written <a href="http://www.matusiak.eu/numerodix/blog/index.php/2009/05/02/introducing-solarbeam/">one program</a> in the past using winforms and it was quite painful, so I wanted to try gtk.</p>
<p>To build the gui I naturally use glade, which is the best gui design experience ever. I then have to find out how to connect the signals, write the handlers and all that stuff.</p>
<p>Mono&#8217;s <a href="http://www.go-mono.com/docs/">api docs</a> on <a href="http://www.go-mono.com/docs/index.aspx?link=N%3aGtk">gtk</a> seem quite complete, so you can usually find out what you need to know. I seem to remember looking at these in the past seeing nothing but <em>&#8220;Documentation for this section has not yet been entered&#8221;</em>, so perhaps they have improved this recently. I have to say they do use <a href="http://download.oracle.com/javase/6/docs/api/">the beloved javadoc model</a> of having the left frame list all the classes, which makes navigation a pain. Api doc presentation is not really known to be a cutting edge field, it really could use work. Then again, the presentation of the docs can&#8217;t help reflect the organization of the api to a large extent and if your api is organized as a <a href="http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html">kingdom of nouns</a> rather than <a href="http://docs.python.org/modindex.html">thematic</a> <a href="http://www.ruby-doc.org/stdlib/packages.html">modules</a> then there&#8217;s probably little magic the api doc guy can wield.</p>
<p>Gtk is not as discoverable as it could be, due to the fact that they have invented some terminology. A window resize event is not a <code>ResizeEvent</code>, it&#8217;s an <code>ExposeEvent</code>. When I tried to discover this one I tried connecting all the signals that mention resizing in the api docs and none of them worked. Maybe this one belongs to a base class that wasn&#8217;t listed in the api doc I was looking at? Could be. (You see how api docs matter?)</p>
<p>In general though, I get the impression that the more you know about gtk the more it makes sense, it seems a really well engineered toolkit. This, of course, in stark contrast to winforms, where the more you know about it the worse it gets. I don&#8217;t know what gtk is like in c, but at least under .NET it doesn&#8217;t have the manual memory management &#8220;feature&#8221; of winforms.</p>
<p>Gtk is hugely superior in many ways and that I don&#8217;t think is even debatable. The layouting is great, internationalization support is painless, pango rendering is lovely and lets you use markup etc. One advantage that winforms has is the way it appears under Windows. But this I think is more a theming issue than a toolkit issue. Winforms looks nice under Windows and gtk looks mediocre. On the other hand, if I boot <a href="http://www.go-mono.com/mono-downloads/download.html">Mono&#8217;s livecd</a> with the latest mono on it, and I run the samples there, gtk looks lovely and winforms looks atrocious, even though this is ostensibly supposed to demonstrate how well both of them run on the latest mono. So I take it from this that simply not enough people care about gtk on Windows to make it look better.</p>
<p>For the python coder, you can apply the api docs for c# directly, because the binding exposes the same names to python. This is very helpful. There are also quite a few pygtk examples around the web you can find if you need to discover how to do something in gtk.</p>
<h3>IronPython</h3>
<p>Let&#8217;s start with the positives. If you give it an existing python program and tell it where the standard library is, it will run your program. In this case I had to work around some platform nastiness and patch some code that&#8217;s using <code>os</code> (throwing false positive <code>OSError</code>s on file renames) that works fine on CPython/Windows but doesn&#8217;t on IronPython/Windows. But in general it seems to work quite well.</p>
<p><strong>Development experience</strong></p>
<p>But if all you&#8217;re going to do is write code using the standard library, there is absolutely no reason to use IronPython. How do you access .NET apis from Python? No, seriously, that&#8217;s not a rhetorical question. IronPython ships with a number of assemblies, so where are the api docs for these? Are they browsable on the web? Are they viewable locally? The only thing I can see documentation wise is, next to <code>IronPython.dll</code>, something called <code>IronPython.xml</code>. It seems to be an aggregate of all the inline api comments in the source code. Is this it? Is this how you&#8217;re supposed to view the api doc? IronPython 2.7 does something interesting. It ships a file called <code>IronPython.chm</code>, but only the .msi installer package includes this. As I&#8217;m sure the IronPython guys are well aware, the installer is Windows only and the .chm file too is Windows only (although I think there is something called <a href="http://www.kchmviewer.net/">kchmviewer</a> that could read it).</p>
<p>In fact, the .chm file is basically the original Python 2.7 documentation (written in .rst, which compiles to html), renamed to IronPython 2.7, and includes a few additional pages about IronPython. Except that instead of throwing the html files on the web or including them in the download, they have compiled them into a .chm which they only give to the Windows people. And this is supposed to be a platform independent runtime? Is this a prank?</p>
<p>IronPython ships some examples, but it&#8217;s not enough to figure out how to use the apis. To write a veritable IronPython gui program you need to produce an assembly, which has to be compiled with <code>-target:winexe</code> so that it does not show a terminal window on Windows. The simplest way seems to be to write a wrapper in c#, using the runtime hosting api, and execute your python in there. That&#8217;s what the <a href="http://pyjamaproject.org/Pyjama">Pyjama project</a> uses (they also use gtk#), so I was able to look that up. But when I needed to set up <code>sys.argv</code> and <code>sys.version</code> using the hosting apis before launching the python I had no idea how. How are you supposed to find this out without documentation?</p>
<p>It turns out that you need to do something like this:</p>
<blockquote><p>ScriptScope scope = Python.ImportModule(runtime, &#8220;sys&#8221;);<br />
scope.SetVariable(&#8221;version&#8221;, &#8220;ironpython&#8221;);</p></blockquote>
<p>Easy, right? Yeah, when you know it, of course it is. But what if you didn&#8217;t? How would you know that there is a function <code>ImportModule</code> in the <code>Python</code> namespace?</p>
<p>And how do you set <code>sys.argv</code>?</p>
<blockquote><p>IronPython.Runtime.List lst = (IronPython.Runtime.List) scope.GetVariable(&#8221;argv&#8221;);</p></blockquote>
<p>How would you know that <code>IronPython.Runtime.List</code> is the class that models a python list? You can use it like a python list:</p>
<blockquote><p>lst.append(&#8221;program.py&#8221;);</p></blockquote>
<p>In the end your best bet might actually be <code>dir()</code>. So how do you find out what&#8217;s in the <code>Python</code> namespace when coding c#? Use python:</p>
<blockquote><p>clr.AddReference(&#8221;IronPython&#8221;)<br />
import IronPython<br />
print dir(IronPython.Hosting.Python)</p></blockquote>
<p>You could actually use this method to recursively <code>dir()</code> the assemblies and produce a map of what&#8217;s in there, generating some kind of api doc in the end, but this is getting quite out of hand now.</p>
<p>At this point I was going to mention <a href="http://msdn.microsoft.com">msdn</a> and how that ought to host all the .NET related api docs you could ever want, but I see that the site is even worse than it used to be and I don&#8217;t have the palest idea of where to find anything anymore. I can only imagine that if you install the latest Visual Studio Ultimate Premium Professional it will enhance your hard drive with untold gigabytes of xml compiled to a proprietary binary file format worth of api docs, which you can only browse in the proprietary api doc reader, which internally just renders html anyway. But actually, since IronPython was <a href="http://www.theregister.co.uk/2010/10/22/microsoft_kills_dynamic_languages_projects/">ousted</a> by Microsoft and since it has the stigma of being an open source project, it could well be that it would be considered too tainted to include its api docs in the Visual Studio-installed doc browser.</p>
<p>As your final recourse, I suggest you warm up your <code>grep</code>, <code>git clone</code> this <a href="https://github.com/IronLanguages/main">IronLanguages repo</a> and hope for the best.</p>
<p><strong>Debugging</strong></p>
<p>When I try this somewhere in my hosted python program:</p>
<blockquote><p>v = None + 1</p></blockquote>
<p>this is what I get:</p>
<blockquote><p>Unhandled Exception: Microsoft.Scripting.ArgumentTypeException: unsupported operand type(s) for +: &#8216;NoneType&#8217; and &#8216;int&#8217;</p></blockquote>
<p>And the rest of the stack trace doesn&#8217;t mention the python code at all. Better than &#8220;Segmentation fault&#8221;, yes, but not by a whole lot. No filename, no line number.</p>
<p>This being the case I would strongly recommend developing your python with CPython first and then, once it&#8217;s in good shape, build the gui so you can do most of your debugging under CPython.</p>
<p><strong>Upgrade cycle</strong></p>
<p>I mentioned IronPython 2.7 earlier, but funny thing, I&#8217;ve never actually tried it. The 2.7 release is compiled against .NET 4.0, which is not supported by the mono packages in Ubuntu. I thought that since I have everything working with .NET 2.0/IronPython 2.6 I could just throw in the newer assemblies, run my makefile and compile it against .NET 4.0, on a mono release recent enough to support 4.0 (such as the mono livecd I mentioned before). But no deal. And if you just install .NET 4.0 under Windows it doesn&#8217;t come with a compiler or anything, so there&#8217;s no way to try it.</p>
<h3>IronPython + Gtk</h3>
<p>So how responsive is an ironpython/gtk application, even a tiny one like this?</p>
<p>Start up speed on my Ubuntu system is something like 4s, which is just about fast enough not to notice that it runs on IronPython instead of CPython. But Ubuntu uses gtk natively, so the libraries are in memory. On Windows it varies from a warm start of 6s to 20s+, for a cold start. In the worst case the first hello message from python appears after maybe 5s, so the rest must be accounted for by loading gtk.</p>
<p>Once it&#8217;s running, it can be a bit sluggish, in particular halting the program on Ubuntu sometimes seems to freeze the gui for a few seconds before it goes away. On Windows the issue (as usual) seems to be io. This program scans the filesystem whenever the input parameters change, which produces a list of files that is eventually displayed in the gui. But I&#8217;m not convinced that it&#8217;s any slower than CPython/Windows.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2011/04/09/ironpython-gtk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nametrans: renaming with search/replace</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2011/03/25/nametrans-renaming-with-search-replace/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2011/03/25/nametrans-renaming-with-search-replace/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 17:06:14 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=3159</guid>
		<description><![CDATA[Keeping filenames properly organized is a pain when all you have available for the job is renaming files one by one. It&#8217;s most disheartening when there is something you have to do to all the files in the current directory. This is where a method of renaming by search and replace, just as in a [...]]]></description>
			<content:encoded><![CDATA[<p>Keeping filenames properly organized is a pain when all you have available for the job is renaming files one by one. It&#8217;s most disheartening when there is something you have to do to all the files in the current directory. This is where a method of renaming by search and replace, just as in a text document, would help immensely. Something like this perhaps:</p>
<p><img class="aligncenter size-full wp-image-3191" title="nametrans_ss" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_ss.png" alt="nametrans_ss" width="293" height="64" /></p>
<h3>Simple substitutions</h3>
<p>The simplest use is just a straight search and replace. All the files in the current directory will be tried to see if they match the search string.</p>
<pre class="bash">$ nametrans.py <span style="color: #ff0000;">"apple"</span> <span style="color: #ff0000;">"orange"</span>
 * I like apple.jpg    -&gt; I like orange.jpg
 * pineapple.jpg       -&gt; pineorange.jpg
 * The best apples.jpg -&gt; The best oranges.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_applelist">nametrans_applelist</a></p>
<p>There are also a number of options that simply common tasks. Options can be combined and the order in which they are set does not matter.</p>
<p><strong>Ignore case</strong></p>
<p>Matching against strings with different case is easy.</p>
<pre class="bash">$ nametrans.py -i <span style="color: #ff0000;">"pine"</span> <span style="color: #ff0000;">"wood"</span>
 * pineapple.jpg -&gt; woodapple.jpg
 * Pinetree.jpg  -&gt; woodtree.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_ignorecase">nametrans_ignorecase</a></p>
<p><strong>Literal</strong></p>
<p>The search string is actually a regular expression. If you use characters that have a special meaning in regular expressions then set the literal option and it will do a standard search and replace. (If you don&#8217;t know what regular expressions are, just use this option always and you&#8217;ll be fine.)</p>
<pre class="bash">$ nametrans.py --lit <span style="color: #ff0000;">"(1)"</span> <span style="color: #ff0000;">"1"</span>
 * funny picture <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>.jpg -&gt; funny picture <span style="color: #cc66cc;">1</span>.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_literal">nametrans_literal</a></p>
<p><strong>Root</strong></p>
<p>If you prefer the spelling &#8220;oranje&#8221; instead of &#8220;orange&#8221; you can replace the G with a J. This will also match the extension &#8220;.jpg&#8221;, however. So in a case like this set the root option to consider only the root of the filename for matching.</p>
<pre class="bash">$ nametrans.py --root <span style="color: #ff0000;">"g"</span> <span style="color: #ff0000;">"j"</span>
 * I like orange.jpg    -&gt; I like oranje.jpg
 * pineorange.jpg       -&gt; pineoranje.jpg
 * The best oranges.jpg -&gt; The best oranjes.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_root">nametrans_root</a></p>
<h3>Hygienic uses</h3>
<p>Short of specific cases of transforms, there are some general options that have to do with maintaining consistency in filenames that can apply to many scenarios.</p>
<p><strong>Neat</strong></p>
<p>The neat option tries to make filenames neater by capitalizing words and removing characters that are typically junk. It also does some simple sanity checks like removing spaces or underscores at the ends of the name.</p>
<pre class="bash">$ nametrans.py --neat
 * _funny___picture_<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>.jpg -&gt; Funny - Picture <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>.jpg
 * i like apple.jpg         -&gt; I Like Apple.jpg
 * i like peach.jpg         -&gt; I Like Peach.jpg
 * pineapple.jpg            -&gt; Pineapple.jpg
 * the best apples.jpg      -&gt; The Best Apples.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_neat">nametrans_neat</a></p>
<p><strong>Lower</strong></p>
<p>If you prefer lowercase, here is the option for you.</p>
<pre class="bash">$ nametrans.py --lower
 * Funny - Picture <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>.jpg -&gt; funny - picture <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>.jpg
 * I Like Apple.jpg        -&gt; i like apple.jpg
 * I Like Peach.JPG        -&gt; i like peach.jpg
 * Pineapple.jpg           -&gt; pineapple.jpg
 * The Best Apples.jpg     -&gt; the best apples.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_lower">nametrans_lower</a></p>
<p>If you want the result of neat and then lowercase, just set them both. (If you like underscores instead of spaces, also set <code>--under</code>.)</p>
<h3>Non-flat uses</h3>
<p>Presuming the files are named consistently you can throw them into separate directories by changing some character into the path separator.</p>
<p>Note: On Windows, the path separator is \ and you may have to write it as &#8220;\\\\&#8221;.</p>
<pre class="bash">$ nametrans.py <span style="color: #ff0000;">" - "</span> <span style="color: #ff0000;">"/"</span>
 * france - nice - seaside.jpg -&gt; france/nice/seaside.jpg
 * italy - rome.jpg            -&gt; italy/rome.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_prefixasdir">nametrans_prefixasdir</a></p>
<p>The inverse operation is to flatten the entire directory tree so that all the files are put in the current directory. The empty directories are removed.</p>
<pre class="bash">$ nametrans.py --flatten
 * france/nice/seaside.jpg -&gt; france - nice - seaside.jpg
 * italy/rome.jpg          -&gt; italy - rome.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_flatten">nametrans_flatten</a></p>
<p>In general, the recursive option will take all files found recursively and make them available for substitutions. It can be combined with other options to do the same thing recursively as would otherwise happen in a single directory.</p>
<pre class="bash">$ nametrans.py -r --neat
 * france/nice/seaside.jpg -&gt; France/Nice/Seaside.jpg
 * italy/rome.jpg          -&gt; Italy/Rome.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_recursive">nametrans_recursive</a></p>
<p>In recursive mode the whole path will be matched against. You can make sure the matching only happens against the file part of the path with <code>--files</code> or only the directory part with <code>--dirs</code>.</p>
<h3>Special uses</h3>
<p><strong>Directory name</strong></p>
<p>Sometimes filenames carry no useful information and serve only to maintain them in a specific order. The typical case is pictures from your camera that have meaningless sequential names, often with gaps in the sequence where you have deleted some pictures that didn&#8217;t turn out well. In this case you might want to just use the name of the directory to rename all the files sequentially.</p>
<pre class="bash">$ nametrans.py -r --dirname
 * rome/DSC00001.jpg -&gt; rome/rome <span style="color: #cc66cc;">1</span>.jpg
 * rome/DSC00007.jpg -&gt; rome/rome <span style="color: #cc66cc;">2</span>.jpg
 * rome/DSC00037.jpg -&gt; rome/rome <span style="color: #cc66cc;">3</span>.jpg
 * rome/DSC00039.jpg -&gt; rome/rome <span style="color: #cc66cc;">4</span>.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_dirname">nametrans_dirname</a></p>
<p><strong>Rename sequentially</strong></p>
<p>Still in the area of sequential names, at times the numbers have either too few leading zeros to be sorted correctly or too many unnecessary zeros. With this option you can specify how many leading zeros you want (and if you don&#8217;t say how many, it will find out on its own). Based on <a href="http://www.matusiak.eu/numerodix/blog/index.php/2008/05/01/renaming-sequentially/">an old piece of code</a> that has been integrated.</p>
<pre class="bash">$ nametrans.py -r --renseq <span style="color: #cc66cc;">1</span>:<span style="color: #cc66cc;">3</span>
 * rome/<span style="color: #cc66cc;">1</span>.jpg   -&gt; rome/<span style="color: #cc66cc;">001</span>.jpg
 * rome/<span style="color: #cc66cc;">7</span>.jpg   -&gt; rome/<span style="color: #cc66cc;">007</span>.jpg
 * rome/<span style="color: #cc66cc;">14</span>.jpg  -&gt; rome/<span style="color: #cc66cc;">014</span>.jpg
 * rome/<span style="color: #cc66cc;">18</span>.jpg  -&gt; rome/<span style="color: #cc66cc;">018</span>.jpg
 * rome/<span style="color: #cc66cc;">123</span>.jpg -&gt; rome/<span style="color: #cc66cc;">123</span>.jpg</pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/nametrans_renseq">nametrans_renseq</a></p>
<p>The argument required here means <code>field:width</code>, so in a name like:</p>
<blockquote><p>series14_angle3_shot045.jpg</p></blockquote>
<p>the number 045 can be shortened to 45 with &#8220;3:2&#8243; (third field from the beginning) or &#8220;-1:2&#8243; (first field from the end).</p>
<p>Get it from sourceforge:</p>
<ul>
<li><a href="http://nametrans.sourceforge.net/">nametrans</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2011/03/25/nametrans-renaming-with-search-replace/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>everything that is wrong with bookmarks</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2011/02/15/everything-that-is-wrong-with-bookmarks/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2011/02/15/everything-that-is-wrong-with-bookmarks/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 17:01:56 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=3027</guid>
		<description><![CDATA[The history of bookmarks is one of those tragic stories in technology. When bookmarks were first introduced (by Netscape? or maybe it was Mosaic?) they were a huge step forward. Trying to memorize urls or writing them on paper clearly weren&#8217;t methods that worked well. The idea &#8212; and so simple too &#8212; that the [...]]]></description>
			<content:encoded><![CDATA[<p>The history of bookmarks is one of those tragic stories in technology. When bookmarks were first introduced (by Netscape? or maybe it was Mosaic?) they were a huge step forward. Trying to memorize urls or writing them on paper clearly weren&#8217;t methods that worked well. The idea &#8212; and so simple too &#8212; that the browser could remember the urls for you was the perfect solution.</p>
<p>Sadly, since the &#8220;big bang&#8221; of bookmarks there have been precious few new explosions.</p>
<h3>The basic problem</h3>
<p>The introduction of bookmarks, welcome as it was, created a problem that remains with us today. Once you start bookmarking pages, you inevitably produce a list of bookmarks that becomes more chaotic and less useful the longer it gets. Sure, a list of bookmarks is useful when you can look at it and quickly know what is there, and when you can see the bookmark you want to load right now.</p>
<p>But when you start having to scroll the list, and not only that but use the PageUp/PageDown keys to scroll the list quicker, it&#8217;s a good sign that it&#8217;s getting out of hand.</p>
<p>A collection of bookmarks is all well and good, but it needs some kind of structure superimposed on it to remain effective.</p>
<h3>The bookmark toolbar</h3>
<p>The bookmark toolbar encapsulates the insight that some bookmarks are more important than others and offers a number of improvements:</p>
<ol>
<li>Allows marking some bookmarks as more important/more frequently used.</li>
<li>Gives them better visibility.</li>
<li>Provides quicker access to them (by not having to go into the bookmark menu).</li>
</ol>
<p>The bookmarks are displayed on a toolbar, either as links or as links-within-folders.</p>
<p><img class="aligncenter size-full wp-image-3055" title="badbookmarks-toolbar" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/badbookmarks-toolbar.png" alt="badbookmarks-toolbar" width="293" height="199" /></p>
<p>Despite how useful this feature is, browsers have historically treated it as something of a marginal feature. Firefox, for instance, used to view the launcher toolbar as just another folder in the bookmarks collection (albeit with a special name, like &#8220;Personal Toolbar Folder&#8221;), which you could accidentally rename or delete, and then it wouldn&#8217;t show up as a toolbar anymore.</p>
<p>Another thing that matters a lot to the usability of the toolbar is the drag-and-dropability of bookmarks onto the toolbar, into the folders, and from one place to another. Even today, for instance, in Google Chrome I can&#8217;t reorder the items in a folder on the toolbar without opening the Bookmark Manager.</p>
<h3>Import/export (and the silo)</h3>
<p>It hardly needs stating that once you have a bookmark collection in one browser, you don&#8217;t want to manually recreate it if you decide to use another one. Browsers have historically been reluctant about giving out their bookmarks. All too often, despite making a show of offering to import your bookmarks from another browser, the import mechanism has bordered on the useless.</p>
<p>First and foremost, every browser vendor since the Ice Age has been eager to supply you with a tasty selection of bookmarks that he was convinced you would love. Importing your own bookmarks, therefore, could at best be seen as a supplement. No browser would ever just take your existing bookmarks and overwrite its own vendor-supplied ones, which is exactly what the user wants. Instead, it would stash them somewhere in the bookmark collection, well out of sight. Any additional metadata that was implicitly stored in your bookmarks would often be lost, like the order in which they were listed.</p>
<p>In particular, the browser would make no bones about trying to find out if you have a bookmark toolbar in there, and replace it with its own (despite the browser having a toolbar feature that worked exactly the same).</p>
<p><img class="aligncenter size-full wp-image-3057" title="badbookmarks-ff-toolbar" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/badbookmarks-ff-toolbar.png" alt="badbookmarks-ff-toolbar" width="451" height="167" /></p>
<p><img class="aligncenter size-full wp-image-3059" title="badbookmarks-bad-import" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/badbookmarks-bad-import.png" alt="badbookmarks-bad-import" width="450" height="309" /></p>
<p>So having done an &#8220;import&#8221;, you would typically have to manually organize your bookmarks, nuke the stupid vendor bookmarks, and sometimes you&#8217;d even have to recreate the folder structure of your bookmark toolbar, all before you had been able to achieve the same state as in your other browser.</p>
<p>This kind of situation is standard silo behavior. By making the import feature so mediocre, the browser vendor would pretty much ensure that the user would not switch browsers without paying a high price for it. Simply using more than one browser on a daily basis, with an easy way to manage your bookmarks across them by a quick sync, is just not realistic.</p>
<h3>Bookmark sync (and more silo)</h3>
<p>A way of keeping your bookmarks synced across computers has been a no-brainer feature since the era when people started accessing the web both at home and at school/work. And yet, a working synchronization feature is a pretty recent development in bookmarks. I recall some failed attempts with Firefox extensions in the remote past, but at last it is here.</p>
<p>A number of browsers have a sync feature now, and it&#8217;s a big step forward in bookmarks. Even if your bookmark collection is a mess, you can at least have the same mess all over the place. Clean it up and it&#8217;s clean everywhere.</p>
<p>And yet, bookmark sync is yet more silo behavior: you can sync your bookmarks from Opera to Opera, but not from Opera to Firefox. The fact that bookmark sync doesn&#8217;t do the same half-assed job of the import feature might seem strange, but the motive is very obvious:</p>
<ul>
<li>ability to have your bookmarks up to date in <em>our</em> browser on every computer = good for the vendor</li>
<li>ability to have your bookmarks up to date in every browser = bad for the vendor</li>
</ul>
<p>Browser vendors know very well that if bookmark sync worked as poorly as bookmark import, they couldn&#8217;t sell it as a feature, because noone would use it.</p>
<h3>Bad page titles</h3>
<p>Strangely enough, I&#8217;ve come all this way without mentioning just about the most glaring problem that bookmarks have: bad page titles. Since the name of the bookmark is simply the title of the page in 99.99% of the cases, the title ought to be both descriptive and concise. Instead, we have historically seen that web creators much prefer titles that are variations on this theme:</p>
<blockquote><p>The Excessively Long Title Of My Website Which Is Very Nice Indeed: Section Title: Article Title</p></blockquote>
<p>With titles like that, all too often you can&#8217;t even see the title of the article in your bookmark list, because the text is truncated somewhere in the middle.</p>
<p>Quite apart from the length problem, web sites often prefer to give articles catchy titles rather than descriptive ones. So with a title like:</p>
<blockquote><p>Something Amusing That Makes You Think About What The Page Really Is About</p></blockquote>
<p>you have the short term benefit of being amused at the cost of the long term benefit of a descriptive title.</p>
<h3>Bad metadata</h3>
<p>Bookmarks belong eminently to the category of things where the number of items is so large that it would be great to have a way of automating the retrieval/organization of the items.</p>
<p>Yet, despite announcements from Mozilla in the past that they would soon obliterate the old model of bookmarks-as-a-list, and introduce a new and all-conquering search based approach, we still have the list. The fact is that bookmarks don&#8217;t contain enough metadata to make search useful. A bookmark has two pieces of data:</p>
<ol>
<li>The name of the bookmark.</li>
<li>The url.</li>
</ol>
<p>Sure, some browsers give you the option to store other things too, like tags, but if we all agree that the user can&#8217;t be bothered to keep their bookmarks organized, let&#8217;s not pretend he will actually input any of the optional stuff. And even if he does, 90% of his bookmarks won&#8217;t have any other data associated with them, so we&#8217;re back to the short list above.</p>
<p>So why doesn&#8217;t search make sense? Because much too often neither the title nor the url contains any of the keywords that you would want to use in order to find this bookmark. Web sites don&#8217;t pay too much attention to titles, and the real data that would be useful to search is the page itself, which is not available.</p>
<h3>Bookmark oblivion</h3>
<p>What should seem ironic is that bookmarking a page often has the effect of not bookmarking it at all. The bookmark is saved somewhere in the long list and then never seen again, either because the list is too long to really bother looking at beyond the most recently added items, or because the page title is useless, or because it was bookmarked &#8220;for future reference&#8221;, and by the time we return to this topic we&#8217;ve forgotten about the bookmark.</p>
<p>We tend to grow pretty oblivious as to what&#8217;s in our bookmarks. Over time, some pages expire, others drift out of our sphere of interest, yet the bookmark collection doesn&#8217;t get updated.</p>
<p>Just about the most obvious feature a browser might offer is to try loading the bookmarks from time to time, in the background, and marking the ones that return 404.</p>
<p>Another idea might be to offer to list bookmarks according to how often they are loaded, making the never used ones fall to the bottom of the list. Applying this to the bookmark folder might be especially useful, so the user doesn&#8217;t have to reorder the bookmarks to make the frequent ones quicker to reach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2011/02/15/everything-that-is-wrong-with-bookmarks/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>ansicolor: because the view is better in colors</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2010/08/06/ansicolor-because-the-view-is-better-in-colors/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2010/08/06/ansicolor-because-the-view-is-better-in-colors/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 13:35:59 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=2730</guid>
		<description><![CDATA[If you&#8217;re a coder you probably try to modularize everything to death on a daily basis. If not, your practices are a little suspicious.   Alas, it&#8217;s not so easy to knock out something that I can say with confidence will be reusable in the future. One piece of functionality I keep reimplementing is [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a coder you probably try to modularize everything to death on a daily basis. If not, your practices are a little suspicious. <img src='http://www.matusiak.eu/numerodix/blog/wp-includes/images/smilies/nervous.png' alt=':nervous:' class='wp-smiley' />  Alas, it&#8217;s not so easy to knock out something that I can say with confidence will be reusable in the future. One piece of functionality I keep reimplementing is output in colors, because it&#8217;s hugely helpful to making things look more distinct. The first time I wrote this module I knew I would be using it again and I wished to make it nice and reusable, but I didn&#8217;t know what the future uses would be. So I put that off until &#8220;later&#8221;. In the meantime I copy/pasted it a couple of times into other projects. Shameful, but effective.</p>
<p>I finally got around to organizing these types of bits that have no specific place of their own into a new github repository, appropriately named &#8220;pybits&#8221;. It holds the <a href="http://www.matusiak.eu/numerodix/blog/index.php/2010/04/25/pretty-printing-for-everyone/">pretty printer</a> and this rewritten ansicolor module, and it&#8217;ll probably grow with the ages.</p>
<p>But to business. Anyone spitting out ansi escapes who has figured out the system knows it&#8217;s trivial to make a color chart. So to keep the tradition going, here&#8217;s proof that ansicolor is able to enumerate the colors:</p>
<p><img class="aligncenter size-full wp-image-2737" title="ansicolor_chart" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/ansicolor_chart.png" alt="ansicolor_chart" width="333" height="337" /></p>
<p>Notice that section at the bottom about highlighting colors. As you might be able to deduce by sheer logic, black and white are not great colors for highlighting something in a terminal, because they are typically used respectively as the background and foreground of the term (or vice versa). (The colors of a term can actually be anything, but black and white are the common ones. Ideally, code should detect this at runtime, but I don&#8217;t know of a way to check for this. Besides, lots of programs [eg. portage] do make this assumption also.) So the highlighting colors are supposed to be useful for when you want to output a wall of text and mark something in the middle of it, so the user can spot it.</p>
<p>Suppose you are (as I have been in the past) developing a regular expression and you can&#8217;t get it right on the first try (yeah, unbelievable, I know). Well, what you do is highlight the string so you can see how the matching worked out:</p>
<p><img class="aligncenter size-full wp-image-2751" title="ansicolor_1regex" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/ansicolor_1regex.png" alt="ansicolor_1regex" width="242" height="46" /></p>
<p>Regular expressions tend to get hairy (yes way) so it helps to compare their results when you&#8217;re trying to unify two half-working variants into one. Adding a second regex will show the matches from both. Where they overlap the styling is bold:</p>
<p><img class="aligncenter size-full wp-image-2753" title="ansicolor_2regex" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/ansicolor_2regex.png" alt="ansicolor_2regex" width="242" height="60" /></p>
<p>Think of the green highlighting as a layer of paint on the wall. You then paint a layer of yellow on top, but you don&#8217;t cover exactly the same area. So where the green wasn&#8217;t painted over it&#8217;s still green. Where the yellow covered it, the paint is thicker. And where the yellow didn&#8217;t overlap the green it&#8217;s just plain yellow.</p>
<p>Adding a third regex potentially produces segments highlighted three layers thick, so there the color becomes reverse.</p>
<p><img class="aligncenter size-full wp-image-2756" title="ansicolor_3regex" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/ansicolor_3regex.png" alt="ansicolor_3regex" width="243" height="76" /></p>
<p>And then bold <em>and</em> reverse.</p>
<p><img class="aligncenter size-full wp-image-2759" title="ansicolor_4regex" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/ansicolor_4regex.png" alt="ansicolor_4regex" width="242" height="89" /></p>
<p>ansicolor doesn&#8217;t support background colors, but that&#8217;s a product of my use so far, I&#8217;ve never needed it. I don&#8217;t think they improve readability.</p>
<p>You will find this cutting edge technology in the repo:</p>
<ul>
<li><a href="http://github.com/numerodix/pybits">pybits</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2010/08/06/ansicolor-because-the-view-is-better-in-colors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cygwin essentials</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2010/07/21/cygwin-essentials/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2010/07/21/cygwin-essentials/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 12:16:31 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=2698</guid>
		<description><![CDATA[This isn&#8217;t really appropriate for a blog entry, because it&#8217;s bound to be updated over and over, but I need a place to keep these notes.
Essential packages (not including pre-selected):

xinit. Effectively what is called Cygwin/X. (Creates a new shortcut in the start menu called XWin Server that you probably should stick in your startup list.) [...]]]></description>
			<content:encoded><![CDATA[<p>This isn&#8217;t really appropriate for a blog entry, because it&#8217;s bound to be updated over and over, but I need a place to keep these notes.</p>
<p>Essential packages (not including pre-selected):</p>
<ul>
<li>xinit. Effectively what is called <a href="http://x.cygwin.com/">Cygwin/X</a>. (Creates a new shortcut in the start menu called XWin Server that you probably should stick in your startup list.) With this you can run gvim, xterm etc.</li>
<li>binutils (if you want strings)</li>
<li>file</li>
<li>git, gitk</li>
<li>openssh</li>
<li>ping</li>
<li>python</li>
<li>rsync</li>
<li>vim, gvim</li>
<li>wget, curl</li>
<li>zip, unzip</li>
<li>make/patch</li>
</ul>
<p>Decent terminals:</p>
<ul>
<li>mintty</li>
<li><a href="http://code.google.com/p/puttycyg/">puttycyg</a> (ie. putty modded to use locally) You have to get this one separately, but it has a nicer feel to it imo.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2010/07/21/cygwin-essentials/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>pretty printing for everyone!</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/25/pretty-printing-for-everyone/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/25/pretty-printing-for-everyone/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 16:32:00 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=2651</guid>
		<description><![CDATA[I&#8217;ve been toying with the idea of trying my hand a generic pretty printer module for a while. Lately I&#8217;ve had to deal with cyclic object graphs and things like that, where having a dump of the data is pretty handy. Granted there is a pprint module in the standard library. But what it does [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been toying with the idea of trying my hand a generic pretty printer module for a while. Lately I&#8217;ve had to deal with cyclic object graphs and things like that, where having a dump of the data is pretty handy. Granted there is a <code>pprint</code> module in the standard library. But what it does is format and print iterables (lists, dicts, tuples..), it doesn&#8217;t attempt to show you the contents of an object. Of course, when you&#8217;re messing with objects this is very useful to have.</p>
<p>So I thought that I would build a recursive iterable that I can give to <code>pprint</code>. Here&#8217;s an example:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">class</span> Node<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    classatt = <span style="color: #483d8b;">'hidden'</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = name
&nbsp;
a, b, c, d = Node<span style="color: black;">&#40;</span><span style="color: #483d8b;">'A'</span><span style="color: black;">&#41;</span>, Node<span style="color: black;">&#40;</span><span style="color: #483d8b;">'B'</span><span style="color: black;">&#41;</span>, Node<span style="color: black;">&#40;</span><span style="color: #483d8b;">'C'</span><span style="color: black;">&#41;</span>, Node<span style="color: black;">&#40;</span><span style="color: #483d8b;">'D'</span><span style="color: black;">&#41;</span>
a.<span style="color: black;">refs</span> = <span style="color: black;">&#91;</span>b, d<span style="color: black;">&#93;</span>
b.<span style="color: black;">refs</span> = <span style="color: black;">&#91;</span>c<span style="color: black;">&#93;</span>
c.<span style="color: black;">refs</span> = <span style="color: black;">&#91;</span>a<span style="color: black;">&#93;</span>
d.<span style="color: black;">refs</span> = <span style="color: black;">&#91;</span>c<span style="color: black;">&#93;</span></pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/pretty_printing_object.py">pretty_printing_object.py</a></p>
<p>This will give you:</p>
<pre class="python"><span style="color: black;">&#123;</span><span style="color: #483d8b;">'__type__'</span>: <span style="color: #483d8b;">'&lt;Node {id0}&gt;'</span>,
 <span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">"'A'"</span>,
 <span style="color: #483d8b;">'refs'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'__type__'</span>: <span style="color: #483d8b;">'&lt;Node {id1}&gt;'</span>,
           <span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">"'B'"</span>,
           <span style="color: #483d8b;">'refs'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'__type__'</span>: <span style="color: #483d8b;">'&lt;Node {id2}&gt;'</span>,
                     <span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">"'C'"</span>,
                     <span style="color: #483d8b;">'refs'</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'dup &lt;Node {id0}&gt;'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>,
          <span style="color: black;">&#123;</span><span style="color: #483d8b;">'__type__'</span>: <span style="color: #483d8b;">'&lt;Node {id3}&gt;'</span>,
           <span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">"'D'"</span>,
           <span style="color: #483d8b;">'refs'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'__type__'</span>: <span style="color: #483d8b;">'&lt;Node {id2}&gt;'</span>,
                     <span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">"'C'"</span>,
                     <span style="color: #483d8b;">'refs'</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'dup &lt;Node {id0}&gt;'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span></pre>
<p><i>Download this code: </i><a href="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/pretty_printing_output.py">pretty_printing_output.py</a></p>
<p>There are two things being shown here:</p>
<ul>
<li>node C is reachable through ABC <em>and</em> ADC.</li>
<li>A takes part in two cycles: ABCA and ADCA.</li>
</ul>
<p>It would be nice to have a way to see this from the output. So aside from the object attributes themselves there is also a <code>__type__</code> attribute which tells you the type that you&#8217;re looking at. And it has a marker of the form <code>{id1}</code>, where <code>id1</code> is an identifier for this object, so that you can see where it pops up in a different part of the graph.</p>
<p>Now, suppose we follow A to B to C and then to A. We are now seeing A for the second time. Instead of printing the object again we print a duplicate marker: <code>dup &lt;Node {id0}&gt;</code>. The identifier is supposed to be vim <code>*</code> friendly, so if you pipe the output to vim, put the cursor over it and hit <code>*</code> (also might want to do <code>set hlsearch</code>) then you&#8217;ll see it light up all the other instances of it in the graph.</p>
<p><img class="alignnone size-full wp-image-2659" title="pretty_printing_gvim" src="http://www.matusiak.eu/numerodix/blog/wp-content/uploads/pretty_printing_gvim.png" alt="pretty_printing_gvim" width="518" height="400" /></p>
<p>Well, that&#8217;s all for now. It&#8217;s definitely not the last word in pretty printing, but it&#8217;s useful already.</p>
<p>I thought maybe github&#8217;s gists would be appropriate for something like this:</p>
<ul>
<li><a href="http://gist.github.com/378503">pp module</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/25/pretty-printing-for-everyone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>lessons from &#8220;Coders at work&#8221;</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/16/lessons-from-coders-at-work/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/16/lessons-from-coders-at-work/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 12:56:19 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=2612</guid>
		<description><![CDATA[I already mentioned Coders at work in an earlier entry. The point of this one is not to write a review, but to make a note for myself of what I&#8217;ve gotten out of the book. I think I could do better to read more books with a pen and a pad so I have [...]]]></description>
			<content:encoded><![CDATA[<p>I already mentioned <a href="http://www.matusiak.eu/numerodix/blog/index.php/2010/04/14/systems-are-too-complicated-dammit/">Coders at work</a> in an earlier entry. The point of this one is not to write a review, but to make a note for myself of what I&#8217;ve gotten out of the book. I think I could do better to read more books with a pen and a pad so I have a better chance of exploiting the content.</p>
<p>So these are notes to myself. I wouldn&#8217;t take it upon myself to summarize a more general listing of notes that would somehow apply to the average person, because I think we&#8217;re all in very different places in the universe that is called &#8220;learning to program (well)&#8221;, and every person has to figure out for himself what he most needs to learn relative to where he now is.</p>
<h3>Advice: Read code</h3>
<p>Read other people&#8217;s code, &#8220;<em>open black boxes</em>&#8220;. This is something I never really do, I should start. Just take some codebase and check it out, get used to the practice. Reading code is not the easiest thing to get into, so here are some tips:</p>
<ol>
<li>First, get it to build.<br />
Sometimes everything you have to do to build it already teaches you a number of things about the codebase. And once you have it built, you can start making changes to it and try out little things dynamically.</li>
<li>Read while building.<br />
Making builds for any codebase can be hairy and painful, so parallelize this activity with code reading. Great way to use the time you&#8217;d otherwise waste in between debugging the build.</li>
</ol>
<h3>Advice: Write unit tests for new library</h3>
<p>You&#8217;ve found a library for something that you&#8217;ve never used before: how do you figure out how to use it? Write unit tests. Some libraries have bad unit tests (or no tests) to begin with, so it could be a way to improve it. In any case you can test your basic hypotheses of how the library works.</p>
<h3>Ideas to investigate</h3>
<ol>
<li>OO and classes vs prototypes (JavaScript).</li>
<li>&#8220;There is a lack of reuse in OO because there is too much state inside&#8221;. Libraries must expose too much of their innards through APIs, functional programming model should be better at this.</li>
</ol>
<h3>Pointers</h3>
<p>Articles:</p>
<ol>
<li>Richard P. Gabriel &#8211; <a href="http://dreamsongs.com/WorseIsBetter.html">Worse Is Better</a></li>
</ol>
<p>Blogs:</p>
<ol>
<li><a href="http://technikhil.wordpress.com/2010/07/06/how-to-read-code-a-primer/">How to read code – a primer</a></li>
</ol>
<p>Books:</p>
<ol>
<li>Douglas Crockford &#8211; JavaScript: The Good Parts<br />
In the absence of the book, Crockford&#8217;s <a href="http://yuiblog.com/crockford/">lecture series on JavaScript</a> is probably a good start.</li>
<li>William Strunk, Jr. and E.B. White &#8211; The Elements of Style<br />
For writing better English.</li>
<li>Steve McConnell &#8211; Code Complete<br />
On software engineering process and best practices.</li>
<li>Gerald Weinberg &#8211; The Psychology of Computer Programming</li>
</ol>
<p>Talks:</p>
<ol>
<li>Joshua Bloch &#8211; <a href="http://www.google.com/url?sa=t&amp;source=web&amp;oi=video_result&amp;cad=7495955179002248300&amp;ct=res&amp;cd=1&amp;ved=0CBEQtwIwAA&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DaAb7hSCtvGw&amp;ei=vgDGS5zTOqLqmwO1rojNDg&amp;usg=AFQjCNHDlUh9h76aVaSxJcYPvisZ01xJ_g&amp;sig2=hOipBwPiaX0f8E5pHBWqDQ">How to Design a Good API and Why it Matters</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/16/lessons-from-coders-at-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>systems are too complicated, dammit!</title>
		<link>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/14/systems-are-too-complicated-dammit/</link>
		<comments>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/14/systems-are-too-complicated-dammit/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 16:06:57 +0000</pubDate>
		<dc:creator>numerodix</dc:creator>
				<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://www.matusiak.eu/numerodix/blog/?p=2620</guid>
		<description><![CDATA[I&#8217;m reading Peter Seibel&#8217;s book &#8220;Coders at work&#8221;. It&#8217;s a collection of interviews with famous programmers. This is the kind of book I really like, it&#8217;s not a technical book, but it&#8217;s a meta sort of book where these people tell you what they think about various relevant issues in the industry. And not just [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m reading Peter Seibel&#8217;s book &#8220;Coders at work&#8221;. It&#8217;s a collection of interviews with famous programmers. This is the kind of book I really like, it&#8217;s not a technical book, but it&#8217;s a meta sort of book where these people tell you what they think about various relevant issues in the industry. And not just issues that concern them directly, but general trends too. It&#8217;s a very easy read, perfect for the plane or the airport.</p>
<p>There are 15 interviews and almost all these people started playing with computers sort of roughly before there were computers. So if there is a theme running through the book, it is this:</p>
<ol>
<li>Kids today don&#8217;t understand how the metal works.</li>
<li>I don&#8217;t like all these layers of software.</li>
</ol>
<p>I think it&#8217;s an understandable point of view coming from people who&#8217;ve written operating systems and compilers and coded assembly and machine code because there was nothing else available. But I don&#8217;t find it a very helpful perspective.</p>
<p>The basic complaint is this:</p>
<ol>
<li>Things used to be simple.</li>
<li>Instead of remaining simple, they got complex, but not in a good way (ie. bad technical decisions).</li>
</ol>
<p>I think this is an &#8220;argument from nostalgia&#8221;, essentially. Back in the days, systems were simpler. Today they are very complicated. And so we wish things were simpler. But this is because some people were present more or less at the &#8220;birth&#8221; of computer science. The field went from zero and just keeps expanding. That&#8217;s normal, though.</p>
<p>If a physicist said &#8220;<em>I hate how when you discover a layer of particles, there&#8217;s always something smaller than that!</em>&#8221; would people nod in agreement? I remember learning about <a href="http://en.wikipedia.org/wiki/Atomic_orbital">atomic orbitals</a> and not understanding them and I kept thinking &#8220;<em>what was wrong with the <a href="http://en.wikipedia.org/wiki/Bohr_model">Bohr model</a>, that one was so much simpler and nicer</em>?&#8221;</p>
<p>The difference between physics and computer science is that in physics there&#8217;s noone to blame for what is there. There is this sense of &#8220;<em>nature is the goddess who bestows gifts upon us and we have the privilege to explore them</em>&#8220;. In computer science we&#8217;re not trying to explain or discover anything, we make all this stuff up!</p>
<p>In physics there&#8217;s no way you can remove the complexity and be left with a simple system, the complexity is there at all levels. But in computers you can delete everything save for the kernel and you indeed have a simple system. (Better yet, delete the kernel too and install a simpler one that you wrote yourself.)</p>
<p>The fundamental difference, to me, is that there is someone to blame. There is noone to blame for atomic orbitals and &#8220;<em>why do they have to be so complicated??</em>&#8220;, but there is someone to blame for every programming language and every system. I don&#8217;t think for a minute that we wouldn&#8217;t do the same in physics if we had the chance, though.</p>
<h3>What&#8217;s Plan B?</h3>
<p>Of course, the difference between the physical sciences and computer science raises the old &#8220;is it a science?&#8221; question, but at any rate it is <em>becoming</em> more like physics in the sense of a top to bottom system that is difficult to understand at all levels.</p>
<p>In physics you don&#8217;t say things like &#8220;<em>I would like to throw all this out and start over, make it simple</em>&#8220;. This is something you can totally do in computers, but chances are you&#8217;re not gonna have much impact. Sometimes people bemoan how there hasn&#8217;t been any innovation in operating systems in 30 years. So go write your own, see how many people you can convince to use it.</p>
<p>In a way, the answer is right there. The fact that there aren&#8217;t any new operating systems taking over from the old ones, _means_ that the old ones have succeeded. They&#8217;ve successfully laid that layer of bricks that has proven to be a strong enough abstraction to move away from <em>that</em> layer in the system and focus our attention on something higher up. They&#8217;re not works of art in terms of simplicity and purity, but neither are layers of abstraction in physics. *ducks*</p>
<p>Complexity is often presented as a mistake, but the fact that we have all this complexity is not really an accident, it has to be there to do the kinds of things that we want to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.matusiak.eu/numerodix/blog/index.php/2010/04/14/systems-are-too-complicated-dammit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

