<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>The Brush Blog</title>
	
	<link>http://blog.brush.co.nz</link>
	<description>software, electronics, web</description>
	<lastBuildDate>Mon, 14 Sep 2009 12:55:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/micropledge/blog" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">micropledge/blog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fmicropledge%2Fblog" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>catdoc ported to Windows</title>
		<link>http://blog.brush.co.nz/2009/09/catdoc-windows/</link>
		<comments>http://blog.brush.co.nz/2009/09/catdoc-windows/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 12:55:37 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=481</guid>
		<description><![CDATA[Recently I had to automatically extract text from a bunch of Word documents under Windows. I liked the looks of catdoc, but didn&#8217;t see a native Win32 port around. The source code looked so very close to compiling under MinGW, so I made the few minor changes necessary and got it working (catdoc, catppt, and [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had to automatically extract text from a bunch of Word documents under Windows. I liked the looks of <a href='http://wagner.pp.ru/~vitus/software/catdoc/'>catdoc</a>, but didn&#8217;t see a native Win32 port around. The source code looked so very close to compiling under MinGW, so I made the few minor changes necessary and got it working (catdoc, catppt, and xls2csv). Native Win32 executables, support for long filenames, etc.</p>

<p>Basically all I did was:</p>

<ul>
<li>Add a glob function from the BSD-licensed <a href='http://synesis.com.au/software/unixem.html'>unixem library</a>.</li>
<li>Change a few of the <code>ifdef __MSDOS__</code> to <code>if defined(__MSDOS__) || defined(_WIN32)</code>.</li>
<li>Make one or two other minor changes to <code>fileutil.c</code>, including the <code>exe_dir()</code> function.</li>
</ul>

<p>Nothing special, and it&#8217;s not perfect. But here is a zip of the compiled binaries and (GPL-licensed) source code, just for you:</p>

<p style='text-align: center; font-size: 150%; font-weight: bold;'><a href='http://blogstatic.micropledge.com/2009/09/catdoc-0.94.2-win32.zip'>catdoc-0.94.2-win32.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/09/catdoc-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code generation with X-Macros in C</title>
		<link>http://blog.brush.co.nz/2009/08/xmacros/</link>
		<comments>http://blog.brush.co.nz/2009/08/xmacros/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 00:55:14 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=445</guid>
		<description><![CDATA[C and C++ are relatively non-dynamic languages, and one thing this means is that not repeating yourself (aka DRY) is often harder than in a language like Python.

For instance, when you&#8217;ve got a config file, a config structure, config defaults, and a config printer, you want all those things to come from a single spec. [...]]]></description>
			<content:encoded><![CDATA[<p>C and C++ are relatively non-dynamic languages, and one thing this means is that not repeating yourself (aka <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>) is often harder than in a language like Python.</p>

<p>For instance, when you&#8217;ve got a config file, a config structure, config defaults, and a config printer, you want all those things to come from a single spec. One good way around this problem is code generation &mdash; for example, using an XML spec with Python and Cheetah templates to generate C code.</p>

<p>But for simple C projects this can be overkill. And it turns out the age-old C preprocessor contains a few goodies that help with DRY programming. As the <a href="http://en.wikipedia.org/wiki/C_preprocessor#X-Macros">Wikipedia article</a> says, <i>one little-known usage pattern of the C preprocessor is known as &#8220;X-Macros&#8221;</i>.</p>

<h4>So what are X-Macros?</h4>

<p>An X-Macro is a standard preprocessor macro (or just a header file) that contains a list of calls to a sub-macro. For example, here&#8217;s the <code>config.def</code> file for the INI-parsing code we&#8217;ll be looking at (uses my <a href="http://code.google.com/p/inih/">simple INI parser library</a>):</p>

<pre class='prettyprint'><code>/* CFG(section, name, default) */
CFG(protocol, version, "0")
CFG(user, name, "Fatty Lumpkin")
CFG(user, email, "fatty@lumpkin.com")
#undef CFG
</code></pre>

<p>That&#8217;s an X-Macro that defines a config file with a protocol version and user name and email fields. If we weren&#8217;t following DRY, our main code would specify the field names in the <code>struct</code> definition, repeat them for setting the default values, and repeat them again for loading and printing the structure.</p>

<p>To do this in X-Macro style, we just <code>#include "config.def"</code> repeatedly, but <code>#define CFG</code> to what we need each time we include it. Sticking with show-me-the-code, here&#8217;s a program that loads, stores, and prints our config:</p>

<pre class='prettyprint'><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include "../ini.h"

/* define the config struct type */
typedef struct {
    #define CFG(s, n, default) char *s##_##n;
    #include "config.def"
} config;

/* create one and fill in its default values */
config Config = {
    #define CFG(s, n, default) default,
    #include "config.def"
};

/* process a line of the INI file, storing valid values into config struct */
int handler(void *user, const char *section, const char *name,
            const char *value)
{
    config *cfg = (config *)user;

    if (0) ;
    #define CFG(s, n, default) else if (stricmp(section, #s)==0 &amp;&amp; \
        stricmp(name, #n)==0) cfg-&gt;s##_##n = strdup(value);
    #include "config.def"

    return 1;
}

/* print all the variables in the config, one per line */
void dump_config(config *cfg)
{
    #define CFG(s, n, default) printf("%s_%s = %s\n", #s, #n, cfg-&gt;s##_##n);
    #include "config.def"
}

int main(int argc, char* argv[])
{
    if (ini_parse("test.ini", handler, &amp;Config) &lt; 0)
        printf("Can't load 'test.ini', using defaults\n");
    dump_config(&amp;Config);
    return 0;
}
</code></pre>

<p>Note that <code>config.def</code> is included 4 times, so you&#8217;d have to repeat yourself 3&nbsp;times with no X-Macros. I admit it&#8217;s not beautiful artwork. But it&#8217;s not too ugly either &mdash; and it gets the job done with nothing but C&#8217;s built-in code generator.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/08/xmacros/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Site Doublers: Website optimization</title>
		<link>http://blog.brush.co.nz/2009/08/site-doublers/</link>
		<comments>http://blog.brush.co.nz/2009/08/site-doublers/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 04:16:17 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=418</guid>
		<description><![CDATA[Recently we&#8217;ve been running some Google AdWords and doing some SEO (Search Engine Optimization), and I must say it helps to know what you don&#8217;t know.

John Hyde of Site Doublers has been a great help on this score. He&#8217;s a consultant that helps you as a business optimize traffic to your website, via search engines [...]]]></description>
			<content:encoded><![CDATA[<p>Recently we&#8217;ve been running some Google AdWords and doing some SEO (Search Engine Optimization), and I must say it helps to know what you don&#8217;t know.</p>

<p>John Hyde of <a href="http://www.sitedoublers.com/">Site Doublers</a> has been a great help on this score. He&#8217;s a consultant that helps you as a business optimize traffic to your website, via search engines and advertisements, and helps you convert visitors to sales once people are going to your website.</p>

<p>John&#8217;s been very professional to work with: he knows what he&#8217;s on about, he asks the right questions, and he does his homework. All of which to say, if you run a website, talk to John on <b>+64 3 942 3799</b> or visit his <a href='http://www.sitedoublers.com/'>website</a>:</p>

<p style='text-align: center;'><a href='http://www.sitedoublers.com/' title="Go to Site Doublers"><img style='padding: 0; border: solid 2px black;' src='http://blogstatic.micropledge.com/2009/08/sitedoublers.png' alt='SiteDoublers logo' width='526' height='120'/></a></p>

<p><i>P.S. And no, John didn&#8217;t pay me to write this. :-)</i></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/08/site-doublers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fabricate: The better build tool</title>
		<link>http://blog.brush.co.nz/2009/07/fabricate/</link>
		<comments>http://blog.brush.co.nz/2009/07/fabricate/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 23:04:27 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=408</guid>
		<description><![CDATA[We&#8217;ve been using Bill McCloskey&#8217;s memoize to build projects for a while now, and it works nicely, but only on Linux.

So enter fabricate. It was developed by us guys at Brush Technology for in-house use, but we thought it was cool enough to release into the wild.

From the project page:


fabricate is a build tool that [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been using Bill McCloskey&#8217;s <a href='http://www.eecs.berkeley.edu/~billm/memoize.html'>memoize</a> to build projects for a while now, and it works nicely, but only on Linux.</p>

<p><a href='http://code.google.com/p/fabricate/'>So enter fabricate.</a> It was developed by us guys at Brush Technology for in-house use, but we thought it was cool enough to release into the wild.</p>

<p>From the project page:</p>

<blockquote><p>
fabricate is a build tool that finds dependencies automatically for any language. It&#8217;s small and just works. No hidden stuff behind your back. It was inspired by Bill McCloskey&#8217;s make replacement, memoize, but fabricate works on Windows as well as Linux.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/07/fabricate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy IP-to-country lookup in Python</title>
		<link>http://blog.brush.co.nz/2009/07/geoip/</link>
		<comments>http://blog.brush.co.nz/2009/07/geoip/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 03:25:46 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=391</guid>
		<description><![CDATA[We&#8217;re branching into the U.S. market with our wedding registry website, Gifty. So first we grabbed a .com domain name, but we also had to make sure the price shows correctly in USD or NZD depending on where you&#8217;re from.

There are a number of tools available for geo-locating someone based on their IP address, including [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re branching into the U.S. market with our wedding registry website, <a href='http://giftyweddings.com/'>Gifty</a>. So first we grabbed a <code>.com</code> domain name, but we also had to make sure the price shows correctly in USD or NZD depending on where you&#8217;re from.</p>

<p>There are a number of tools available for geo-locating someone based on their IP address, including some free ones. <a href='http://www.maxmind.com/'>MaxMind</a> is pretty popular and nice to use, and their free <a href='http://www.maxmind.com/app/geolitecountry'>GeoLite Country</a> database did the trick for me.</p>

<p>Gifty runs on Python, so I wanted something I could just use in pure Python. It turns out that <a href='http://code.google.com/p/pygeoip/'>pygeoip</a> is a nice Python replacement for MaxMind&#8217;s C-based API.</p>

<p>However, I was only interested in the country-code lookup, so I decided to strip it down and release the two-pages-of-Python version I&#8217;m using. Just grab MaxMind&#8217;s <a href='http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz'>database</a> and put the code in Python&#8217;s <code>Lib/site-packages</code> directory:</p>

<p style='text-align: center; font-size: 150%; font-weight: bold;'><a href='http://blogstatic.micropledge.com/2009/07/geoip.py.txt'>get geoip.py</a></p>

<p>And then to use it, simply type:</p>

<pre class='prettyprint'><code>&gt;&gt;&gt; import geoip
&gt;&gt;&gt; geoip.country('202.21.128.102')
'NZ'
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/07/geoip/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Blast from the demoscene past</title>
		<link>http://blog.brush.co.nz/2009/06/scene/</link>
		<comments>http://blog.brush.co.nz/2009/06/scene/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 22:03:17 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=358</guid>
		<description><![CDATA[Do you like the demoscene? Or do you just like smaller, faster, or embedded code? Read on.

When I was 14, I started learning how to program, for at least two reasons:


  My dad could code, and he made some neat stuff, like a code-generating pentomino puzzle solver and a really tiny pop-up editor.
  [...]]]></description>
			<content:encoded><![CDATA[<p><i>Do you like the demoscene? Or do you just like smaller, faster, or embedded code? Read on.</i></p>

<p>When I was 14, I started learning how to program, for at least two reasons:</p>

<ul>
  <li>My dad could code, and he made some neat stuff, like a code-generating <a href="http://www.complang.tuwien.ac.at/forth/pentomino.fs">pentomino puzzle solver</a> and a <a href="http://blog.brush.co.nz/2008/06/snappy-software/#comment-2442">really tiny pop-up editor</a>.</li>
  <li>Because I really liked the <a href="http://en.wikipedia.org/wiki/Demoscene">demoscene</a>.</li>
</ul>

<p>Scratch that. I <i>still like</i> the demoscene. I mean, who else can make incredible 3D <a href="http://www.pouet.net/prod.php?which=3397">tube</a> or <a href="http://www.pouet.net/prod.php?which=4659">lattice</a> demos in a <b>256-byte executable?</b> Try them &#8212; both still run fine under Windows XP.</p>

<p><a href="http://blogstatic.micropledge.com/2009/06/phyure_stars.zip"><img class="border right" src="http://blogstatic.micropledge.com/2009/06/phyure_stars.png" width="195" height="158" alt="Fire effect and starfield" title="Click to download the source code for my old fire effect and starfield" /></a>So I read diskmags and tutes to learn how to program the VGA hardware, push pixels to <code>0xA000:0000</code>, and use <a href="http://en.wikipedia.org/wiki/Mode_X">Mode X</a>. Oh, and I learnt about <code>sin</code> and <code>cos</code> before I learnt at school &#8212; for basic 2D and 3D rotation. Then there were effects: the fire effect, plasma, starfields, wormholes, etc, etc. (Click on the piccy to the right to download some of my old source.)</p>

<p>Anyway, back from <a href="http://www.youtube.com/watch?v=8G_aUxbbqWU">Second Reality</a> to the real thing &#8230;</p>

<p>As I&#8217;ve noted before, I&#8217;m <a href="http://blog.brush.co.nz/2008/07/adobe-reader-9/">not exactly in favour</a> of bloatware. But in today&#8217;s &#8220;a GB here, a GB there&#8221; world, <b>is small still beautiful?</b> I think so, for two reasons:</p>

<h4>Embedded programming</h4>

<p>In the embedded world, size still matters a lot. Microcontrollers are getting bigger and faster, sure, but in electronic products there&#8217;s often a place for the small ones (say 64KB flash, 2KB RAM). Just the other day, I cut our code size by 900 bytes, which was a significant percentage of the total &#8212; less code to download, test, and maintain.</p>

<p>And it&#8217;s not only important for small micros, but also to limit download time and cost for in-field updates. If you want to update code for 1000 units over a fairly slow and costly radio link, small is good.</p>

<p><b>Binary diffs</b> or deltas are really good for this. My brother Berwyn has developed a proof-of-concept binary diffing algorithm which is designed for tiny embedded systems &#8212; <a href="http://brush.co.nz/contact">contact us</a> if you&#8217;re keen to hear more.</p>

<p>Binary diffing isn&#8217;t new, of course &#8212; <a href="http://www.daemonology.net/bsdiff/">bsdiff</a> already does something similar for Firefox&#8217;s updates, so you only need to download a small update. But bsdiff doesn&#8217;t work on small embedded systems, because it uses a compression program which requires a fair amount of RAM (bzip2).</p>

<h4>To go fast, do less</h4>

<p>Yep, as <a href="http://asserttrue.blogspot.com/2009/03/how-to-write-fast-code.html">the guy said</a>: <i>To go fast, do less.</i></p>

<p>And KISS. Keeping it Short and Simple means less code to test, and if you&#8217;re using basically the right approach and algorithm, it usually also means <i>faster</i> code. And to follow my own advice, I&#8217;m keeping this section short.</p>

<h4>Conclusion</h4>

<p>In a word, if you&#8217;re a budding hacker, or the parent of a budding hacker, teach them that small is still beautiful. And get &#8216;em started with the demoscene. There is still a pretty active &#8217;scene community, and here are some starting points:</p>

<ul>
 <li><a href="http://en.wikipedia.org/wiki/Demoscene">Wikipedia article on the demoscene</a></li>
 <li><a href="http://www.pouet.net/">Pouet.net</a>, a great place to download popular demos</li>
 <li><a href="http://www.scene.org/">Scene.org</a>, another good &#8217;scene resource</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/06/scene/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pilot ships through Google Earth</title>
		<link>http://blog.brush.co.nz/2009/05/ships/</link>
		<comments>http://blog.brush.co.nz/2009/05/ships/#comments</comments>
		<pubDate>Thu, 21 May 2009 04:35:02 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=351</guid>
		<description><![CDATA[Paul van Dinther, one of the folks we work with, has released a ship simulation game that uses Google Earth for its &#8220;terrain&#8221; data:


PlanetInAction.com released a new simulation game called Ships. In Ships you take the helm from a choice of 3D ships. What is special about this game is that it makes use of [...]]]></description>
			<content:encoded><![CDATA[<p>Paul van Dinther, one of the folks we work with, has released a ship simulation game that uses Google Earth for its &#8220;terrain&#8221; data:</p>

<blockquote>
<p><i><a href="http://planetinaction.com/">PlanetInAction.com</a> released a new simulation game called <a href="http://planetinaction.com/ships.php">Ships</a>. In Ships you take the helm from a choice of 3D ships. What is special about this game is that it makes use of the rich 3D data present in Google Earth. The entire world is your playground.</i></p>
<p><i>&#8220;Ships&#8221; is a graphically rich environment with intricate visual effects that runs right inside your web-browser. All you need is a small Google Earth plugin. Take control now of the majestic Queen Mary 2 and hit the authentic fog horn as you leave the port of Rotterdam in the Netherlands. If water is not your thing then why not climb aboard the airship Hindenburg and check-out the Swiss alps.</i></p>
</blockquote>

<p>Have fun sailing around the (real) world!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/05/ships/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python’s Ellipsis explained</title>
		<link>http://blog.brush.co.nz/2009/05/ellipsis/</link>
		<comments>http://blog.brush.co.nz/2009/05/ellipsis/#comments</comments>
		<pubDate>Fri, 08 May 2009 03:54:53 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=333</guid>
		<description><![CDATA[As others note, using Python&#8217;s Ellipsis object in slices is rather obscure, and there are hardly any good examples out there. So I thought I&#8217;d do my bit with a nice, simple example, complete with comments:

# Portable way to get the You-Know-Which object without naming it
class __:
 def __getitem__(__, _):
  return _
___ = __()[...]

# [...]]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://stackoverflow.com/questions/118370/how-do-you-use-the-ellipsis-slicing-syntax-in-python">others note</a>, using Python&#8217;s <code>Ellipsis</code> object in slices is rather obscure, and there are hardly any good examples out there. So I thought I&#8217;d do my bit with a nice, simple example, complete with comments:</p>

<pre class='prettyprint'><code># Portable way to get the You-Know-Which object without naming it
class __:
 def __getitem__(__, _):
  return _
___ = __()[...]

# An Ellipsobinary-to-ASCII convertor
class __:
 def __getitem__(__, _):
  return chr(sum(1&lt;&lt;i if _[-i-1] is ___ else 0 for i in range(len(_))))
_ = __()

# Finally, use the That-Which-Must-Not-Be-Named object
print (
 _[...,_,_,...,_,_,_] +
  _[...,...,_,_,...,_,...] +
   _[...,...,_,...,...,_,_] +
    _[...,...,_,...,...,_,_] +
     _[...,...,_,...,...,...,...] +
      _[...,_,...,...,_,_] +
       _[...,_,_,_,_,_] +
        _[...,...,...,_,...,...,...] +
         _[...,...,_,...,...,...,...] +
          _[...,...,...,_,_,...,_] +
           _[...,...,_,...,...,_,_] +
            _[...,...,_,_,...,_,_] +
             _[...,_,_,_,_,...])
</code></pre>

<p>And you thought Python code couldn&#8217;t be <a href="http://en.wikipedia.org/wiki/IOCCC">obfuscated</a>?</p>

<p>Seriously, though &#8230; do any non-<a href="http://www.scipy.org/Tentative_NumPy_Tutorial#line-487">NumPy</a> programmers actually use <code>Ellipsis</code>? I have yet to find other (non-NumPy) uses of it in the wild.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/05/ellipsis/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Knuth, goto, Python, and OOP</title>
		<link>http://blog.brush.co.nz/2009/04/knuth/</link>
		<comments>http://blog.brush.co.nz/2009/04/knuth/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 07:21:39 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=310</guid>
		<description><![CDATA[The year was 1973. Real programmers were still using punch-cards and Pascal. C had barely been invented, and object-oriented programming was hardly a twinkle even in the eyes of top computer scientists. Whether or not to use goto was the hot topic of the day.

Knuth

It was then that Donald Knuth wrote his famous essay Structured Programming [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Literate-Programming-Center-Language-Information/dp/0937073806"><img class="border right" src="http://blogstatic.micropledge.com/2009/04/lp.jpg" alt="Literate Programming by Donald Knuth" width="150" height="224" /></a>The year was 1973. Real programmers were still using punch-cards and Pascal. C had barely been invented, and object-oriented programming was hardly a twinkle even in the eyes of top computer scientists. Whether or not to use <code>goto</code> was the hot topic of the day.</p>

<h4>Knuth</h4>

<p>It was then that Donald Knuth wrote his famous essay <i>Structured Programming with go to Statements</i>. And some essay it is: he covers everything from the current trends on structured programming to premature optimization being the root of all evil. (I read it in <a href="http://www.amazon.com/Literate-Programming-Center-Language-Information/dp/0937073806"><i>Literate Programming</i></a>, but it&#8217;s also available as a <a href="http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf">scanned PDF here</a>.)</p>

<p>He&#8217;s responding to Edsger Dijkstra&#8217;s well-known letter <a href="http://ctp.di.fct.unl.pt/lei/lap/papers/e.w.%20dijkstra%20[1968]%20-%20go%20to%20statement%20considered%20harmful.pdf"><i>Go To Statement Considered Harmful</i></a>, but (in typical Knuth fashion) he covers so much related ground it&#8217;s not funny.</p>

<p>What was striking to me is the <i>context</i> of his discussion. It&#8217;s clear that structured programming &#8212; which we use every day and think is &#8220;common sense&#8221; &#8212; had to be invented, discussed, and refined. Like most inventions, it&#8217;s obvious &#8230; 36 years later.</p>

<h4>goto</h4>

<p>It&#8217;s also obvious that <code>goto</code> (or &#8220;go to&#8221; as Knuth calls it) was much more widely used and abused than it is today. This is probably partly because assembly language was so much more common, but also because &#8220;they&#8221; had to learn that <code>goto</code> isn&#8217;t usually the right abstraction &#8212; in fact, it isn&#8217;t much of an abstraction at all.</p>

<p>Now it&#8217;s 2009, and <code>goto</code> is pretty rare. It&#8217;s still used, of course, but I&#8217;ve usually seen it only in the cases Knuth is talking about: for efficiency, error exits, and for breaking out of certain kinds of loops.</p>

<p>In C you still occassionally need it for cleaning up before error exits, or for breaking out of efficient nested loops, or in generated code, but these days we also have other constructs and other languages that solve 1973&#8217;s problems most of the time.</p>

<p>In C, you have the invaluable <code>break</code> as well as the ability to <code>return</code> early. Knuth advocated the equivalent of C&#8217;s <code>break</code>, implying also that most languages at the time didn&#8217;t have it.</p>

<p>Compilers are also somewhat better at producing optimized code from non-<code>goto</code>ed source: for example, I can program my virtual machine&#8217;s opcode dispatcher as a bunch of <code>case</code> statements, knowing the compiler will probably optimize it into a jump table.</p>

<p>And in most modern high-level languages (C++ and up) you have <i>exceptions</i>, which eliminate the need for error-exit <code>goto</code>s, as well as solve several other problems in a really tidy way.</p>

<h4>Python</h4>

<p>Python is important in this discussion not only because Knuth is keen on beautiful code, but because Knuth &#8220;predicted&#8221; its arrival in several different ways. Here&#8217;s a quote from the last section of his essay:</p>

<blockquote>
<p><i>It seems clear that languages somewhat different from those in existence today would enhance the preparation of structured programs. We will perhaps eventually be writing only small modules which are identified by name as they are used to build larger ones, so that <b>devices like indentation, rather than delimiters,</b> might become feasible for expressing local structure in the source language.</i></p>
</blockquote>

<p>Of course, many languages now have &#8220;small modules which are identified by name as they are used to build larger ones&#8221;, but Python really took Knuth seriously about using indentation as a delimiter.</p>

<p>What&#8217;s more, you can always <a href="http://entrian.com/goto/">add <code>goto</code> to Python</a> if you really need it. :-)</p>

<h4>OOP</h4>

<p>And it gets even more interesting when he goes on to say:</p>

<blockquote>
<p><i>Although our examples don&#8217;t indicate this, it turns out that a given level of abstraction often involves <b>several related routines and data definitions;</b> for example, when we decide to represent a table in a certain way, we simultaneously want to specify the routines for storing and fetching information from that table. The next generation of languages will probably take into account such related routines.</i></p>
</blockquote>

<p>Correct me if I&#8217;m wrong, but doesn&#8217;t that sound awfully like OOP? So in a single essay apparently about <code>goto</code> statements, Knuth predicted modules, Python&#8217;s use of indentation as delimiters, and object-oriented programming. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/04/knuth/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A browser-agnostic plugin system?</title>
		<link>http://blog.brush.co.nz/2009/03/proxymoron/</link>
		<comments>http://blog.brush.co.nz/2009/03/proxymoron/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 08:51:16 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.brush.co.nz/?p=265</guid>
		<description><![CDATA[[Update: I've wrongly been calling extensions "plugins". So this post is actually talking about extensions, not plugins.]

Lately I&#8217;ve been browsing with Google Chrome.It looks and works great, and it&#8217;s quick. But it doesn&#8217;t have plugins.

One of the few plugins I can hardly do without is the Blank Canvas Gmail Signatures add-on. Gmail doesn&#8217;t allow a [...]]]></description>
			<content:encoded><![CDATA[<p><small><i>[Update: I've <a href="http://news.ycombinator.com/item?id=514671">wrongly been calling</a> extensions "plugins". So this post is actually talking about extensions, not plugins.]</i></small></p>

<p><img class="right" style="margin-left: 30px;" src="http://blogstatic.micropledge.com/2009/03/chrome-plugins.jpg" width="175" height="190" alt="Chrome: Where are my plugins?" title="Oh where ... are my plugins?" />Lately I&#8217;ve been browsing with <a href="http://www.google.com/chrome">Google Chrome</a>.<br/>It looks and works great, and it&#8217;s quick. <i>But it doesn&#8217;t have plugins.</i></p>

<p>One of the few plugins I can hardly do without is the <a href="http://blankcanvasweb.com/pages/id_9/n_gmail_signatures/">Blank Canvas Gmail Signatures</a> add-on. Gmail doesn&#8217;t allow a signature per email address, which is a pity, but this add-on handles that nicely. It also allows you to use HTML in your signatures.</p>

<p>Anyway, while cycling to work the other day I thought of an idea for <b>a plugin system that would work in all browsers</b>. My idea was a web proxy running on your local machine that injects HTML or JavaScript into pages from certain URLs, <a href="http://www.greasespot.net/">Greasemonkey</a>-style. With some clever regex-matching and JavaScript injection you could do just about whatever you needed.</p>

<p>But of course &ndash; a deflated ego later &ndash; similar things have already been done. :-)</p>

<h4>Privoxy</h4>

<p>First, I searched for &#8220;browser-agnostic plugin manager&#8221; and discovered <a href="http://www.privoxy.org/">Privoxy</a>. It&#8217;s geared for privacy and blocking ads, but it can do content replacement based on regexes. For instance, there&#8217;s a built-in filter called <code>tiny-textforms</code> that makes your <code>&lt;textarea&gt;</code>s bigger, a bit like <a href="https://addons.mozilla.org/en-US/firefox/addon/3818">this Firefox plugin</a>.</p>

<p>Privoxy looks good and is pretty complete, but it&#8217;s not really geared for plugins (though one of the Privoxy developers <a href="http://osdir.com/ml/web.privoxy.user/2006-11/msg00027.html">mentioned</a> you could probably do Greasemonkey-like stuff with it). Also, Privoxy&#8217;s got a pretty nerdy configuration interface that just wouldn&#8217;t cut it for normal plugin users.</p>

<h4>Proxomitron, Proximodo and BFilter</h4>

<p><a href="http://proxomitron.info/">Proxomitron</a>, <a href="http://proximodo.sourceforge.net/">Proximodo</a> and <a href="http://bfilter.sourceforge.net/">BFilter</a> are three similar web proxy filters that might well do the job. Again, they&#8217;re mainly used for blocking ads, and their GUIs aren&#8217;t really set up as &#8220;plugin managers&#8221;, so I&#8217;m not sure they&#8217;d work for ordinary users.</p>

<h4>Plugins in Chrome</h4>

<p>Google is <a href="http://dev.chromium.org/developers/design-documents/extensions">talking seriously</a> about extension support in Chrome &ndash; perhaps it&#8217;ll happen in the next few months.</p>

<p><i>Stop press!</i> Apparently Chromium already supports <a href="http://dev.chromium.org/developers/design-documents/extensions/userscripts">user scripts</a> &ndash; again, Greasemonkey-style) &ndash; but only in the <a href="http://dev.chromium.org/developers/design-documents/user-scripts">latest developer builds</a>.</p>

<h4>Greasemetal</h4>

<p>In the meantime, there&#8217;s also <a href="http://greasemetal.31tools.com/">Greasemetal</a>, which is a Greasemonkey-compatible tool that uses Chrome&#8217;s inter-process <code>AutomationProxy</code> communications channel. So it&#8217;s not browser-agnostic, but good work Kazuho Oku! I&#8217;ll probably start using this if Chrome doesn&#8217;t hurry up with their extension interface.</p>

<h4>But what about browser-agnostic?</h4>

<p>But back to <i>browser-agnostic</i>. Imagine if all your favourite plugins or Greasemonkey scripts worked in IE, Firefox, Safari, Opera, Chrome, <i>and</i> Lynx.</p>

<p>I don&#8217;t think it would take too much hacking to package up Privoxy as a plugin manager with a decent UI, or perhaps turn it into a browser-agnostic version of Greasemonkey. </p>

<p><b>Any takers, hackers?</b></p>

<p>Or maybe I&#8217;ll get around to it someday. I&#8217;ve got a name for my plugin manager already: Proxymoron.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brush.co.nz/2009/03/proxymoron/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.389 seconds --><!-- Cached page generated by WP-Super-Cache on 2009-11-06 10:25:44 --><!-- Compression = gzip -->
