<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Enter the void *</title>
        <link>http://blog.emillon.org</link>
        <description><![CDATA[Yet another random hacker]]></description>
        <atom:link href="http://blog.emillon.org/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Fri, 11 Nov 2011 00:00:00 UT</lastBuildDate>
        <item>
    <title>Hello, world !</title>
    <link>http://blog.emillon.org/posts/2011-11-11-hello-world.html</link>
    <description><![CDATA[<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">blog </span><span class="ot">::</span> <span class="dt">IO</span> ()<br />blog <span class="fu">=</span><br />  <span class="fu">putStrLn</span> <span class="st">&quot;Hello, world !&quot;</span></code></pre>
<p>This is my first attempt at blogging, I still don’t know what to expect. I will probably write about the following topics :</p>
<ul>
<li>Programming, especially using <a href="http://caml.inria.fr/">functional</a> <a href="http://haskell.org/">languages</a>.</li>
<li>Development of the <a href="http://debian.org/">Debian</a> operating system.</li>
<li><a href="http://en.wikipedia.org/wiki/Static_program_analysis">Static analysis</a> of software.</li>
<li>Computer security.</li>
</ul>
<p>Like some of <a href="http://blog.chmd.fr/going-static.html">my</a> <a href="http://nicdumz.fr/blog/2010/12/why-blogofile/">friends</a>, I decided to use a static blog generator. The first series of posts will be about setting this up with <a href="http://jaspervdj.be/hakyll/">hakyll</a>, git and S3. Stay tuned !</p>]]></description>
    <pubDate>Fri, 11 Nov 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-11-11-hello-world.html</guid>
</item>
<item>
    <title>Hakyll 101</title>
    <link>http://blog.emillon.org/posts/2011-11-21-hakyll-101.html</link>
    <description><![CDATA[<p>So, the recent trend seems to be static blogging. Indeed, as a web application, a blog is mostly read-only. By generating static <code>.html</code> files, one can eliminate :</p>
<ul>
<li>CPU load : static content is what’s easiest to serve, especially with modern servers using <a href="http://manpages.debian.net/cgi-bin/man.cgi?query=sendfile&amp;sektion=2&amp;apropos=0&amp;manpath=Debian+6.0+squeeze">sendfile(2)</a>.</li>
<li>security issues : without dynamic page generation, the attack surface is also vastly reduced. Authentication is moved from a PHP or Python script to the Unix way.</li>
<li>deployment problems : I don’t know a free host that won’t serve static files. I use <a href="http://aws.amazon.com/s3/">S3</a> (and the free tier will often be enough !) but if I am not satisfied, it’s dead simple to migrate.</li>
</ul>
<p>Basically, it’s like moving from a dynamic language to a static one ☺. The only problem is if you want to add comments. The popular solution is <a href="http://disqus.com">Disqus</a> but it is unfortunately a non-free application. I’ll probably stick to it but I fear data lock-in.</p>
<p>As it is fashionable, a <em>lot</em> of tools have appeared : <a href="https://github.com/ametaireau/pelican/">pelican</a>, <a href="http://blogofile.com/">blogofile</a>, <a href="http://ikiwiki.info/">ikiwiki</a>, <a href="http://jekyllrb.com/">jekyll</a>… Being a haskeller, I decided to give <a href="http://jaspervdj.be/hakyll/">hakyll</a> a try.</p>
<p>Hakyll is a haskell library for writing and deploying static websites ; that’s about it. As in a dynamic application, you define routes and how to serve them :</p>
<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">makeCss </span><span class="ot">::</span> <span class="dt">Rules</span><br />makeCss <span class="fu">=</span><br />  void <span class="fu">$</span> match <span class="st">&quot;css/*&quot;</span> <span class="fu">$</span> <span class="kw">do</span><br />      route   idRoute<br />      compile compressCssCompiler</code></pre>
<p>Most rules consist of compiling <a href="http://daringfireball.net/projects/markdown/">markdown</a> to HTML (with the fantastic <a href="http://johnmacfarlane.net/pandoc/">pandoc</a> library) and copying stuff around.</p>
<p>The resulting binary, when compiled, can be run to see previews, build files or even deploy the site.</p>
<pre><code> ~/www/blog [master] % ./blog
ABOUT

This is a Hakyll site generator program. You should always
run it from the project root directory.

USAGE

blog build           Generate the site
blog clean           Clean up and remove cache
blog help            Show this message
blog preview [port]  Run a server and autocompile
blog rebuild         Clean up and build again
blog server [port]   Run a local test server
blog deploy          Upload/deploy your site
</code></pre>
<p>So far I’ve found it very easy to use. That’s it for this first mini-tour. Stay tuned !</p>]]></description>
    <pubDate>Mon, 21 Nov 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-11-21-hakyll-101.html</guid>
</item>
<item>
    <title>Unicode : Math, greek, symbols - you name it !</title>
    <link>http://blog.emillon.org/posts/2011-11-28-unicode-math-greek-symbols-you-name-it.html</link>
    <description><![CDATA[<h2 id="ebcdic-ascii-the-power-of-legacy">EBCDIC, ASCII &amp; the power of legacy</h2>
<p>… and no, that’s not a movie title.</p>
<p>As you know, all your computer knows about is numbers, yet when you type on a keyboard, a character appears on your screen. This is thanks to character encodings.</p>
<p>There are several norms that defines how characters (ie, glyphs) are encoded into numbers. Besides dinosaurs such as <a href="https://secure.wikimedia.org/wikipedia/en/wiki/EBCDIC">EBCDIC</a>, the “classic” way of encoding is <a href="https://secure.wikimedia.org/wikipedia/en/wiki/ASCII">ASCII</a> — that is what most modern<sup><a href="#fn1" class="footnoteRef" id="fnref1">1</a></sup> operating systems use internally.</p>
<p>The problem with ASCII is that it maps every character to a single byte with <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Most_significant_bit">MSB</a> reset, meaning that you can have a maximum of 128 glyphs. It’s “good enough” for English (hey, the A stands for American) but terrible for international characters. This is even worse considering that 32 of them are control characters, ie mostly legacy. Did you ever need to interpret <code>DC2</code>, <code>SI</code> or <code>GS</code> in a program ?</p>
<p>The eighth bit being “reserved” can be used to support “extended characters”. Several vendors (including Microsoft) used the concept of “code pages” to use extra glyphs in the 128–255 range. For example, Latin–1 was used in western europe to display accentuated characters.</p>
<p>If all your data comes from one part of the world, it works fine, but with the following limitations if you need to handle international data :</p>
<ul>
<li>it becomes necessary to have metadata specifying which codepage has to be used.</li>
<li>you have to choose exactly one codepage per document.</li>
</ul>
<p>In other words, a more extensible system is needed. Hopefully, this system exists and is called…</p>
<h2 id="unicode">Unicode</h2>
<p>Unicode separates two notions :</p>
<ul>
<li>what is a character. Unicode include a large collection of glyph names. For example, version 6.0 includes 109449 characters.</li>
<li>how a character is encoded as bytes. More precisely, this is the role of encodings such as <a href="https://secure.wikimedia.org/wikipedia/en/wiki/UTF-8">UTF–8</a>. Usually, they are compatible with ASCII (the byte representation coincides on characters 0–127).</li>
</ul>
<p>What’s nice is that it’s easy to enter Unicode under X11. The last two sections explain how you can configure your system to type (for example) √, β and ✈ !</p>
<h2 id="configure-a-compose-key">Configure a compose key</h2>
<p>A “compose” key, or <code>Multi_key</code> under X11, will begin a character compose sequence. For example, when I type <code>&lt;Multi_key&gt; &lt;s&gt; &lt;q&gt;</code>, a square root (U+221A √) is entered.</p>
<p>To configure a compose key, you can use <a href="http://manpages.debian.net/cgi-bin/man.cgi?query=xmodmap&amp;sektion=1">xmodmap(1)</a>. Put the following into <code>~/.Xmodmap</code> to make your right control key act as a <code>Multi_key</code> :</p>
<pre><code>keysym Control_R = Multi_key
</code></pre>
<p>Unfortunately, this file is not loaded automatically, so you have to run <code>xmodmap ~/.Xmodmap</code> when opening a X session (this can be done automatically if you put in in your <code>~/.xsession</code>, for example).</p>
<h2 id="define-a-.xcompose-mapping">Define a .XCompose mapping</h2>
<p>The second part is to define mappings between key sequences and unicode codepoints. This is the role of the <code>~/.XCompose</code> file.</p>
<p>As described in <a href="http://manpages.ubuntu.com/manpages/precise/en/man5/XCompose.5.html">xcompose(5)</a>, a line looks like :</p>
<pre><code>&lt;Multi_key&gt; &lt;ampersand&gt; &lt;p&gt; &lt;l&gt; &lt;a&gt; &lt;n&gt; &lt;e&gt;     : &quot;✈&quot;   U2708     # AIRPLANE
</code></pre>
<p>ie, a key sequence, a colon, a string and a character name. The comment does not hurt, as usual.</p>
<p>To start your own list of bindings, I suggest <a href="https://github.com/kragen/xcompose">kragen’s repository</a>, which includes an excellent set. And if you need to find a specific unicode character, the <a href="http://kassiopeia.juls.savba.sk/~garabik/software/unicode/">unicode</a> script is very useful !</p>
<p><strong>TL;DR:</strong> Spread the word, ♥ Unicode ☺</p>
<div class="footnotes">
<hr></hr>
<ol>
<li id="fn1"><p>Yes, that excludes AS/400. <a href="#fnref1" class="footnoteBackLink">↩</a></p></li>
</ol>
</div>]]></description>
    <pubDate>Mon, 28 Nov 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-11-28-unicode-math-greek-symbols-you-name-it.html</guid>
</item>
<item>
    <title>What's in an ADT ?</title>
    <link>http://blog.emillon.org/posts/2011-12-14-what-s-in-an-adt.html</link>
    <description><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Algebraic Data Types, or ADTs for short, are a core feature of functional languages such as OCaml or Haskell. They are a handy model of closed disjoint unions and unfortunately, outside of the functional realm, they are only seldom used.</p>
<p>In this article, I will explain what ADTs are, how they are used in OCaml and what trimmed-down versions of them exist in other languages. I will use OCaml, but the big picture is about the same in Haskell.</p>
<h2 id="principles">Principles</h2>
<p>Functional languages offer a myriad of types for the programmer.</p>
<ul>
<li>some <em>base</em> types, such as <code>int</code>, <code>char</code> or <code>bool</code>.</li>
<li>functions, ie <em>arrow</em> types. A function with domain <code>a</code> and codomain <code>b</code> has type <code>a -&gt; b</code>.</li>
<li>tuples, ie <em>product</em> types. A tuple is an heterogeneous, fixed-width container type (its set-theoretic counterpart is the cartesian product) For example, <code>(2, true, 'x')</code> has type <code>int * bool * char</code>. <em>record</em> types are a (mostly) syntactic extension to give name to their fields.</li>
<li>some <em>parametric</em> types. For example, if <code>t</code> is a type, <code>t list</code> is the type of homogeneous linked list of elements having type <code>t</code>.</li>
<li>what we are talking about today, <em>algebraic</em> types (or <em>sum</em> types, or <em>variant</em> types).</li>
</ul>
<p>If product types represent the cartesian product, algebraic types represent the disjoint union. In another words, they are very adapted for a case analysis.</p>
<p>We will take the example of integer ranges. One can say that an integer range is either :</p>
<ul>
<li>the empty range</li>
<li>of the form <code>]-∞;a]</code></li>
<li>of the form <code>[a;+∞[</code></li>
<li>an interval of the form <code>[a;b]</code> (where a ≤ b)</li>
<li>the whole range (ie, ℤ)</li>
</ul>
<p>With the following properties :</p>
<ul>
<li>Disjunction : no range can be of two forms at a time.</li>
<li>Injectivity : if <code>[a;b]</code> = <code>[c;d]</code>, then <code>a</code> = <code>c</code> and <code>b</code> = <code>d</code> (and similarly for other forms).</li>
<li>Exhaustiveness : it cannot be of another form.</li>
</ul>
<h2 id="syntax-semantics">Syntax &amp; semantics</h2>
<p>This can be encoded as an ADT :</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">type</span> range =<br />  | <span class="dt">Empty</span><br />  | <span class="dt">HalfLeft</span> <span class="kw">of</span> <span class="dt">int</span><br />  | <span class="dt">HalfRight</span> <span class="kw">of</span> <span class="dt">int</span><br />  | <span class="dt">Range</span> <span class="kw">of</span> <span class="dt">int</span> * <span class="dt">int</span><br />  | <span class="dt">FullRange</span></code></pre>
<p><code>Empty</code>, <code>HalfLeft</code>, <code>HalfRight</code>, <code>Range</code> and <code>FullRange</code> are <code>t</code>’s <em>constructors</em>. They are the only way to build a value of type <code>t</code>. For example, <code>Empty</code>, <code>HalfLeft 3</code> and <code>Range (2, 5)</code> are all values of type <code>t</code><sup><a href="#fn1" class="footnoteRef" id="fnref1">1</a></sup>. They each have a specific <em>arity</em> (the number of arguments they take).</p>
<p>To <em>deconstruct</em> a value of type <code>t</code>, we have to use a powerful construct, <em>pattern matching</em>, which is about matching a value against a sequence of patterns (yes, that’s about it).</p>
<p>To illustrate this, we will write a function that computes the minimum value of such a range. Of course, this can be ±∞ too, so we have to define a type to represent the return value.</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">type</span> ext_int =<br />  | <span class="dt">MinusInfinity</span><br />  | <span class="dt">Finite</span> <span class="kw">of</span> <span class="dt">int</span><br />  | <span class="dt">PlusInfinity</span></code></pre>
<p>In a math textbook, we would write the case analysis as :</p>
<ul>
<li>min ∅ = +∞</li>
<li>min ]-∞;a] = -∞</li>
<li>min [a;+∞[ = a</li>
<li>min [a;b] = a</li>
<li>min ℤ = -∞</li>
</ul>
<p>That translates to the following (executable !) OCaml code :</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">let</span> range_min x =<br />  <span class="kw">match</span> x <span class="kw">with</span><br />  | <span class="dt">Empty</span> -&gt; <span class="dt">PlusInfinity</span><br />  | <span class="dt">HalfLeft</span> a -&gt; <span class="dt">MinusInfinity</span><br />  | <span class="dt">HalfRight</span> a -&gt; <span class="dt">Finite</span> a<br />  | <span class="dt">Range</span> (a, b) -&gt; <span class="dt">Finite</span> a<br />  | <span class="dt">FullRange</span> -&gt; <span class="dt">MinusInfinity</span></code></pre>
<p>In the pattern <code>HalfLeft a</code>, <code>a</code> is a variable name, so it get bounds to the argument’s value. In other words, <code>match (HalfLeft 2) with HalfLeft x -&gt; e</code> bounds <code>x</code> to 2 in <code>e</code>.</p>
<h2 id="its-functions-all-the-way-down">It’s functions all the way down</h2>
<p>Pattern matching seems magical at first, but it is only a syntactic trick. Indeed, the definition of the above type is equivalent to the following definition :</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">type</span> range<br /><br /><span class="co">(* The following is not syntactically correct *)</span><br /><span class="kw">val</span> <span class="dt">Empty</span> : range<br /><span class="kw">val</span> <span class="dt">HalfLeft</span> : <span class="dt">int</span> -&gt; range<br /><span class="kw">val</span> <span class="dt">HalfRight</span> : <span class="dt">int</span> -&gt; range<br /><span class="kw">val</span> <span class="dt">Range</span> : <span class="dt">int</span> * <span class="dt">int</span> -&gt; range<br /><span class="kw">val</span> <span class="dt">FullRange</span> : range<br /><span class="co">(* Moreover, we know that they are injective and mutually disjoint *)</span><br /><br /><span class="kw">val</span> deconstruct_range :<br />  (<span class="dt">unit</span> -&gt; 'a) -&gt;<br />  (<span class="dt">int</span> -&gt; 'a) -&gt;<br />  (<span class="dt">int</span> -&gt; 'a) -&gt;<br />  (<span class="dt">int</span> * <span class="dt">int</span> -&gt; 'a) -&gt;<br />  (<span class="dt">unit</span> -&gt; 'a) -&gt;<br />  range -&gt;<br />  'a</code></pre>
<p><code>deconstruct_range</code> is what replaces pattern matching. It also embodies the notion of exhaustiveness, because given any value of type <code>range</code>, we can build a deconstructed value out of it.</p>
<p>Its type looks scary at first, but if we look closer, its arguments are a sequence of case-specific deconstructors<sup><a href="#fn2" class="footnoteRef" id="fnref2">2</a></sup> and the value to get “matched” against.</p>
<p>To show the equivalence, we can implement <code>deconstruct_range</code> using pattern patching and <code>range_min</code> using <code>deconstruct_range</code><sup><a href="#fn3" class="footnoteRef" id="fnref3">3</a></sup> :</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">let</span> deconstruct_range<br />      f_empty<br />      f_halfleft<br />      f_halfright<br />      f_range<br />      f_fullrange<br />      x<br />    =<br />  <span class="kw">match</span> x <span class="kw">with</span><br />  | <span class="dt">Empty</span> -&gt; f_empty ()<br />  | <span class="dt">HalfLeft</span> a -&gt; f_halfleft a<br />  | <span class="dt">HalfRight</span> a -&gt; f_halfright a<br />  | <span class="dt">Range</span> (a, b) -&gt; f_range (a, b)<br />  | <span class="dt">FullRange</span> -&gt; f_fullrange ()</code></pre>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="kw">let</span> range_min' x =<br />  deconstruct_range<br />    (<span class="kw">fun</span> () -&gt; <span class="dt">PlusInfinity</span>)<br />    (<span class="kw">fun</span> a -&gt; <span class="dt">MinusInfinity</span>)<br />    (<span class="kw">fun</span> a -&gt; <span class="dt">Finite</span> a)<br />    (<span class="kw">fun</span> (a, b) -&gt; <span class="dt">Finite</span> a)<br />    (<span class="kw">fun</span> () -&gt; <span class="dt">MinusInfinity</span>)<br />    x</code></pre>
<h2 id="implementation">Implementation</h2>
<p>After this trip in denotational-land, let’s get back to operational-land : how is this implemented ?</p>
<p>In OCaml, no type information exists at runtime. Everything exists with a uniform representation and is either an integer or a pointer to a block. Each block starts with a tag, a size and a number of fields.</p>
<p>With the <code>Obj</code> module (kids, don’t try this at home), it is possible to inspect blocks at runtime. Let’s write a dumper for <code>range</code> value and watch outputs :</p>
<pre class="sourceCode"><code class="sourceCode ocaml"><span class="co">(* Range of integers between a and b *)</span><br /><span class="kw">let</span> <span class="kw">rec</span> rng a b =<br />  <span class="kw">if</span> a &gt; b <span class="kw">then</span><br />    []<br />  <span class="kw">else</span><br />    a :: rng (a+<span class="dv">1</span>) b<br /><br /><span class="kw">let</span> view_block o =<br />  <span class="kw">if</span> (Obj<span class="kw">.</span>is_block o) <span class="kw">then</span><br />    <span class="kw">begin</span><br />      <span class="kw">let</span> tag = Obj<span class="kw">.</span>tag o <span class="kw">in</span><br />      <span class="kw">let</span> sz = Obj<span class="kw">.</span>size o <span class="kw">in</span><br />      <span class="kw">let</span> f n =<br />        <span class="kw">let</span> f = Obj<span class="kw">.</span>field o n <span class="kw">in</span><br />        <span class="kw">assert</span> (Obj<span class="kw">.</span>is_int f);<br />        Obj<span class="kw">.</span>obj f<br />      <span class="kw">in</span><br />      tag :: List<span class="kw">.</span>map f (rng <span class="dv">0</span> (sz<span class="dv">-1</span>))<br />    <span class="kw">end</span><br />  <span class="kw">else</span> <span class="kw">if</span> Obj<span class="kw">.</span>is_int o <span class="kw">then</span><br />    [Obj<span class="kw">.</span>obj o]<br />  <span class="kw">else</span><br />    <span class="kw">assert</span> <span class="kw">false</span><br /><br /><span class="kw">let</span> examples () =<br />  <span class="kw">let</span> p_list l =<br />    String<span class="kw">.</span>concat <span class="st">&quot;;&quot;</span> (List<span class="kw">.</span>map string_of_int l)<br />  <span class="kw">in</span><br />  <span class="kw">let</span> explore_range r =<br />    print_endline (p_list (view_block (Obj<span class="kw">.</span>repr r)))<br />  <span class="kw">in</span><br />  List<span class="kw">.</span>iter explore_range<br />    [ <span class="dt">Empty</span><br />    ; <span class="dt">HalfLeft</span> <span class="dv">8</span><br />    ; <span class="dt">HalfRight</span> <span class="dv">13</span><br />    ; <span class="dt">Range</span> (<span class="dv">2</span>, <span class="dv">5</span>)<br />    ; <span class="dt">FullRange</span><br />    ]</code></pre>
<p>When we run <code>examples ()</code>, it outputs :</p>
<pre><code>0
0;8
1;13
2;2;5
1
</code></pre>
<p>We can see the following distinction :</p>
<ul>
<li>0-ary constructors (<code>Empty</code> and <code>FullRange</code>) are encoded are simple integers.</li>
<li>other ones are encoded blocks with a constructor number as tag (0 for <code>HalfLeft</code>, 1 for <code>HalfRight</code> and 2 for <code>Range</code>) and their argument list afterwards.</li>
</ul>
<p>Thanks to this uniform representation, pattern-matching is straightforward : the runtime system will only look at the tag number to decide which constructor has been used, and if there are arguments to be bound, they are just after in the same block.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Algebraic Data Types are a simple model of disjoint unions, for which case analyses are the most natural. In more mainstream languages, some alternatives exist but they are more limited to model the same problem.</p>
<p>For example, in object-oriented languages, the Visitor pattern is the natural way to do it. But class trees are inherently “open”, thus breaking the exhaustivity property.</p>
<p>The closest implementation is tagged unions in C, but they require to roll your own solution using <code>enum</code>s, <code>struct</code>s and <code>union</code>s. This also means that all your hand-allocated blocks will have the same size.</p>
<p>Oh, and I would love to know how this problem is solved with other paradigms !</p>
<div class="footnotes">
<hr></hr>
<ol>
<li id="fn1"><p>Unfortunately, so is <code>Range (10, 2)</code>. The invariant that a ≤ b has to be enforced by the programmer when using this constructor. <a href="#fnref1" class="footnoteBackLink">↩</a></p></li>
<li id="fn2"><p>For 0-ary constructors, the type has to be <code>unit -&gt; 'a</code> instead of <code>'a</code> to allow side effects to happen during pattern matching. <a href="#fnref2" class="footnoteBackLink">↩</a></p></li>
<li id="fn3"><p>More precisely, we would have to show that any function written with pattern matching can be adapted to use the deconstructor instead. I hope that this example is general enough to get the idea. <a href="#fnref3" class="footnoteBackLink">↩</a></p></li>
</ol>
</div>]]></description>
    <pubDate>Wed, 14 Dec 2011 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2011-12-14-what-s-in-an-adt.html</guid>
</item>
<item>
    <title>ZSH suffix aliases</title>
    <link>http://blog.emillon.org/posts/2012-01-17-zsh-suffix-aliases.html</link>
    <description><![CDATA[<p>I recently changed my login shell to use <a href="http://www.zsh.org/">zsh</a> instead of the venerable <a href="http://www.gnu.org/software/bash/">bash</a>. I am still wondering why I didn’t make the change earlier. Zsh’s infamous slowness almost not perceptible, at least with the default configuration.</p>
<p>One cool feature present in zsh is the notion of <em>suffix alias</em> (described in <a href="http://linux.die.net/man/1/zshbuiltins">zshbuiltins(1)</a>). Quick example :</p>
<pre><code>$ alias -s pdf=evince
$ filename.pdf
</code></pre>
<p>… will open filename.pdf under evince, as if <code>evince filename.pdf</code> had been typed. Handy !</p>
<p>But it is not restricted to files : the command is executed whenever the command line matches a suffix alias. So, for example you can define :</p>
<pre><code>alias -s git='git clone'
</code></pre>
<p>… so that everytime you paste a URL ending in <code>git</code>, say <code>git://git.debian.org/git/aptitude/aptitude.git</code>, it will be <code>git-clone</code>d.</p>]]></description>
    <pubDate>Tue, 17 Jan 2012 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2012-01-17-zsh-suffix-aliases.html</guid>
</item>

    </channel> 
</rss>

