<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title></title>
  <link href="http://vedang.me/atom.xml" rel="self"/>
  <link href="http://vedang.me/"/>
  <updated>2012-02-24T00:08:33+05:30</updated>
  <id>http://vedang.me/</id>
  <author>
    <name>Vedang Manerikar</name>
    
  </author>

  
  <entry>
    <title>Composability and Compojure</title>
    <link href="http://vedang.me/techlog/2012/02/23/composability-and-compojure"/>
    <updated>2012-02-23T23:57:00+05:30</updated>
    <id>http://vedang.me/techlog/2012/02/23/composability-and-compojure</id>
    <content type="html">&lt;p&gt;Caveat: This post needs some rudimentary knowledge of Compojure. Compojure is a web framework for Clojure, and if you don't understand what that means, then you should probably head over to the &lt;a href=&quot;https://github.com/weavejester/compojure/wiki&quot;&gt;Compojure docs&lt;/a&gt;. Compojure exposes us to a beautifully &lt;em&gt;composable&lt;/em&gt; abstraction, and this post is an attempt to show why that is a great thing.&lt;/p&gt;

&lt;p&gt;In order to understand the Compojure framework, let us write a small &lt;code&gt;cello world&lt;/code&gt; app. The code snippets in this post are a means to explain a concept, they may not work as-is. The full, working code is available at &lt;a href=&quot;https://gist.github.com/1893532/&quot;&gt;this&lt;/a&gt; gist. Okay then, let's get started.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Here is what the basic routes function would look like:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;basic_routes.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/defroutes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;main-routes&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello World&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/bye/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Goodbye World&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;route/not-found&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Compojure uses Ring to handle requests and responses. These terms (request/response) don't mean 'objects' (to those of you from the OOP world) of any kind, they are just hash-maps used to &lt;em&gt;represent&lt;/em&gt; the idea. They are data, and as such, can be manipulated in any way we want. Ring has a simple philosophy: write functions which accept a request and return a response. Such functions are called &lt;em&gt;handlers&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cc/GET&lt;/code&gt; helper macro - and it's ilk - asks the user for a request-method (specified by the GET in the name cc/GET), a route (string representing uri), and a handler(H1). The macro becomes a handler (H2) which returns the result of &lt;code&gt;(H1 req)&lt;/code&gt; if the route and the method of the incoming request match the specified route and request-method, otherwise it returns nil. Wow, that was a mouthful, wasn't it?. Stop snickering and saying &quot;That's what she said&quot;. So anyway, this is our first introduction to composability in Compojure. We have a macro that takes a handler and gives us another handler. As long as we are dealing in handlers, composability allows us to ignore any implementation complexity.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cc/defroutes&lt;/code&gt; macro takes a name and a list of handlers and returns a handler (H3) which runs all the handlers in the list on the request until one of them returns a non-nil value, else it returns nil. Finally, it binds the name to the handler so that we can call it. Simple, isn't it?&lt;/p&gt;

&lt;p&gt;So if you think you've understood it so far, tell me if adding this route to our main routes will work or not:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;composability-one-oh-one.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello*&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/defroutes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;hello-routes&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello/name/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello Vedang&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello/city/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello from Pune!&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Well, yes! &lt;code&gt;cc/defroutes&lt;/code&gt; gives us a handler&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;, and that's really all cc/GET cares about!&lt;/p&gt;

&lt;p&gt;Having an abstraction of this form allows us to do many things easily, knowing that stuff &lt;em&gt;just works&lt;/em&gt;. For example, let us write some &lt;em&gt;middleware&lt;/em&gt;. What is middleware? Middleware modifies the incoming request or outgoing response in some way that makes us happy. How does this fit into our abstraction? - As a function that takes a handler(H1) and, wait for it, returns another handler(H2). Boom! Confused? Here is what a middleware function looks like:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;middleware.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;verify-secret&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;Verify that secret-key has been sent as a parameter s in the request&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;s=please&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:query-string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;403&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;       &lt;span class=&quot;nv&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;You don&amp;#39;t know the secret word&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})))&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This function gets a handler(H1). It doesn't know or care what that handler is going to do to the request. It returns a new handler(H2) which does the following: it checks to see if the incoming request knows that the secret word s is &quot;please&quot;. If it does, great. Execute H1 on the request and call it a day. Otherwise, return a nil - meaning the request in not valid. Now H2 could go through as many other middleware functions as we want, all of them agnostic of any other middleware functions. Each middleware will return a modified handler(H3, H4, ... Hn), and we will run the final handler on the request.&lt;/p&gt;

&lt;p&gt;Here is what the final code would look like&lt;sup id='fnref:2'&gt;&lt;a href='#fn:2' rel='footnote'&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;compojure-middleware.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;span class='line'&gt;18&lt;/span&gt;
&lt;span class='line'&gt;19&lt;/span&gt;
&lt;span class='line'&gt;20&lt;/span&gt;
&lt;span class='line'&gt;21&lt;/span&gt;
&lt;span class='line'&gt;22&lt;/span&gt;
&lt;span class='line'&gt;23&lt;/span&gt;
&lt;span class='line'&gt;24&lt;/span&gt;
&lt;span class='line'&gt;25&lt;/span&gt;
&lt;span class='line'&gt;26&lt;/span&gt;
&lt;span class='line'&gt;27&lt;/span&gt;
&lt;span class='line'&gt;28&lt;/span&gt;
&lt;span class='line'&gt;29&lt;/span&gt;
&lt;span class='line'&gt;30&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;; Define some Hello routes&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/defroutes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;hello-routes&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello/name/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello Vedang&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello/city/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello from Pune!&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;; Our main routes function.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/defroutes&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;main-routes*&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Cello World&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/bye/&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rur/response&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Goodbye World&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cc/GET&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/hello*&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;hello-routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;route/not-found&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;h1&amp;gt;Page not found&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;; A middleware function&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;verify-secret&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;Verify that secret-key has been sent as a parameter s in the request&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;= &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;s=please&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:query-string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;403&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;       &lt;span class=&quot;nv&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;You don&amp;#39;t know the secret word&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;;; Wrap my main routes in middleware&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;main-routes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;#39;main-routes*&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                     &lt;span class=&quot;nv&quot;&gt;verify-secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;;; Start app with main routes&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run-jetty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;&amp;#39;main-routes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:port&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:join?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;main-routes*&lt;/code&gt; is a handler which matches the incoming uris to ones we support, &lt;code&gt;verify-secret&lt;/code&gt; will make sure that the incoming requests know the secret word. We can go a really long way with functions that take a request and return a response. Compojure gives us a great DSL to deal with the web. It's composability facilitates building elegant systems and frameworks.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
    &lt;ol&gt;
        &lt;li id='fn:1'&gt;Actually, we got lucky in this case. `cc/defroutes` is a macro. When we say `(cc/defroutes name &amp; handlers)` the code is replaced to become `(def name handlerfn)`. Luckily for us though, def returns the variable which was just defined, and it works out okay in the end. The aim was to show composability in action, not to espouse a coding style. Never do this in actual code. &lt;a href='#fnref:1' rev='footnote'&gt;↩&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:2'&gt;Apparently, we can't get line spacing in the octopress codeblock &lt;a href='#fnref:2' rev='footnote'&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;



</content>
  </entry>
  
  <entry>
    <title>Switch Statements in Python</title>
    <link href="http://vedang.me/techlog/2011/08/07/switch-statements-in-python"/>
    <updated>2011-08-07T13:21:00+05:30</updated>
    <id>http://vedang.me/techlog/2011/08/07/switch-statements-in-python</id>
    <content type="html">&lt;p&gt;Today I went through some old Python code and noticed this pattern through out:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;messy-ifs.py &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='py'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;somefunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;this&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;do_this_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;that&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;do_that_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;huh&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;duh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c&quot;&gt;# lots more elifs.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;prevent_horrible_crash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This code should ideally have been a switch-case, but Python does not support a &lt;code&gt;switch&lt;/code&gt; statement. Proponents of OOP believe that &lt;code&gt;switch&lt;/code&gt; is &lt;em&gt;bad&lt;/em&gt; - second only to &lt;code&gt;goto&lt;/code&gt;. This is not strictly true - both goto and switch can be used elegantly and with great effect. Goto, for example, is great for undoing stacked changes and switch's fall-through behavior allows nicely for 'do things according to the stage I'm at'. However, if you're doing OOP, consider using polymorphism instead.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;I'm not doing OOP, so polymorphism does not apply to me, but I was looking for a way to optimize this code. I was on a code-cleanup spree, in the &quot;flow&quot;, and I thought, &quot;Why don't I use maps to do this?&quot;. Brilliant! It was a really neat idea. Later I found out that this is the accepted way of doing switch-case in Python and I'd done nothing special. So anyway, the code now looked like this:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;maps-as-switch.py &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='py'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;response_map&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;this&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;do_this_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class=&quot;s&quot;&gt;&amp;quot;that&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;do_that_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class=&quot;s&quot;&gt;&amp;quot;huh&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;duh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;response_map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prevent_horrible_crash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;And that would have been that, had I not suddenly developed a conscience. I had replaced perfectly working, mostly readable code with some other code. What if my map solution was slower? What if it was &lt;em&gt;much slower&lt;/em&gt;? I'd done a sizable amount of refactoring, and I did not relish throwing it away. I needed to test my solution, so I wrote some sample code:&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1130352.js?file=switch-speed.py'&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;from timeit import Timer
from random import randint


def switch_if():
    value = randint(1, 10)
    if value == 1:
        return '1'
    elif value == 2:
        return '2'
    elif value == 3:
        return '3'
    elif value == 4:
        return '4'
    elif value == 5:
        return '5'
    elif value == 6:
        return '6'
    elif value == 7:
        return '7'
    elif value == 8:
        return '8'
    elif value == 9:
        return '9'
    else:
        return '10'


def switch_map():
    value = randint(1, 10)
    smap = {1: '1',
            2: '2',
            3: '3',
            4: '4',
            5: '5',
            6: '6',
            7: '7',
            8: '8',
            9: '9',
            10: '10'}
    return smap[value]


t = Timer(setup='from __main__ import switch_if', stmt='switch_if()')
print t.timeit()

t = Timer(setup='from __main__ import switch_map', stmt='switch_map()')
print t.timeit()
&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;The results were disheartening. My replacement code was slower - though only just.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;pre&gt;&lt;code&gt;$ python switch-speed.py
if - 2.08906793594
map - 2.88215684891&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;I tweaked the code a little and moved the creation of the map outside of the &lt;code&gt;switch_map&lt;/code&gt; function. Python can access local variables faster than it can access global variables, but I figured a global dict would still beat the cost of creating the dict every time.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;pre&gt;&lt;code&gt;$ python switch-speed.py
if -  2.08955693245
map -  2.00381493568&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;I breathed a sigh of relief. There was a lesson to be learnt here - test/profile &lt;em&gt;before&lt;/em&gt; you optimize!&lt;/p&gt;

&lt;h4&gt;References and articles:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;More information about switch statements smell - &lt;a href=&quot;http://c2.com/cgi/wiki?SwitchStatementsSmell&quot;&gt;c2.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Goto is not evil - &lt;a href=&quot;http://kerneltrap.org/node/553/2131&quot;&gt;kerneltrap.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Why I Quit StumpWM </title>
    <link href="http://vedang.me/techlog/2011/08/04/why-i-quit-stumpwm"/>
    <updated>2011-08-04T13:41:00+05:30</updated>
    <id>http://vedang.me/techlog/2011/08/04/why-i-quit-stumpwm</id>
    <content type="html">&lt;p&gt;After using &lt;a href=&quot;http://www.nongnu.org/stumpwm/&quot;&gt;StumpWM&lt;/a&gt; for nearly a year, I'm finally quitting and moving back to Gnome. I came to love StumpWM's minimalistic approach, and this isn't an easy decision. So why am I doing it?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pinky Hell&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am (was) a heavy user of Emacs, Tmux and StumpWM. These programs rely heavily on the &lt;code&gt;Ctrl&lt;/code&gt; key. This means that the &lt;code&gt;Ctrl&lt;/code&gt; key and my left pinky finger are pretty much destroyed at this point. With the spectre of RSI looming over my head, StumpWM is the easiest tool to get rid off. I might have less screen-space now, but my fingers will thank me for it.
&lt;!--more--&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What you gain in Functionality, you lose in Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;StumpWM is infinitely configurable. If you have the patience, you can get it to do things that are simply impossible with other Windows Managers. For example, there is a &lt;code&gt;mpd.lisp&lt;/code&gt; module inside the contrib directory which converts StumpWM into a MPD client. A &lt;em&gt;full-fledged client&lt;/em&gt;. This means that all music operations are entirely unobtrusive and &lt;em&gt;always&lt;/em&gt; at your beck and call. MPD with StumpWM has without a doubt been the best music setup I've ever used.&lt;/p&gt;

&lt;p&gt;However, I missed Gnome's integration with Ubuntu - Ubuntu One, Gwibber, Pidgin, event notifications. Even if I &lt;em&gt;could&lt;/em&gt; configure StumpWM for these things, there was too much effort involved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dead processes, High temperatures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt; : Everything I'm about to say now is conjecture. There is no proof that StumpWM is responsible for any of this.&lt;/p&gt;

&lt;p&gt;At 5 days uptime, my system load was touching 2, and my system temperature was at 65 degrees C. &lt;a href=&quot;http://about.me/kiran_kulkarni/&quot;&gt;KK&lt;/a&gt; had a similar number of programs running on his system - this is a guy who uses full-blown &lt;a href=&quot;http://www.compiz.org/&quot;&gt;compiz&lt;/a&gt; effects - his system temperature was 36 degrees and load average was around 1.15. Furthermore, he had a 48 day uptime. KK gleefully told me that it had to be StumpWM that was the problem! He was kidding, but some inquiry around the office showed that my laptop was much worse than the other guys on Ubuntu.&lt;/p&gt;

&lt;p&gt;I also found that Chrome was leaving behind loads of defunct processes on my machine. There were 41 defunct chromium-browser processes when I decided to reboot the laptop and do some monitoring. Within an hour of the reboot, I had 7 defunct processes, CPU temperature was at 45 degrees and the load average was hovering around 1.8. That was the proverbial straw that broke the camel's back. I switched back to Gnome. Later in the day, I thought about actually investigating the behavior of my laptop, but it's been behaving well on Gnome. As I write, I have a day's uptime, a load average of 1.03 and CPU temperature at 37.5 degrees C. Unscientific, but fine by me.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;How I got over the Withdrawal Symptoms:&lt;/h2&gt;

&lt;p&gt;Of all the StumpWM features, there was just one that I simply could not do without - 'run-or-raise'. On StumpWM, you can define hot-keys to behave as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Launch the program if it is not running&lt;/li&gt;
&lt;li&gt;Move focus to the program if it is already running.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I use one Emacs instance, one terminal instance (tmux'ed) and one Chrome instance. I &lt;em&gt;need&lt;/em&gt; to be able to access them with minimal friction. Turns out, a little hackery on compiz is all we need - &lt;code&gt;compiz-send.py&lt;/code&gt; is a nifty little script that sends messages to DBus and interacts with compiz. I can use it along with &lt;code&gt;xdtool&lt;/code&gt; to implement my run-or-raise behavior. Here is a look at my &lt;code&gt;run-or-raise-emacs.sh&lt;/code&gt; script:&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/1130303.js?file=run-or-raise-emacs.sh'&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#!/bin/bash
# get id of emacs
win=$(xdotool search --onlyvisible --class emacs | head -1)

if [ &amp;quot;x$win&amp;quot; = x ]; then
    # Emacs is not running
    # switch to viewport 1, which is my coding viewport
    ~/incoming-src/dotfiles/scripts/compiz-send.py vpswitch switch_to_1_key
    gxmessage -center -timeout 2 -nofocus -buttons &amp;quot;&amp;quot; -borderless &amp;quot;loading emacs...&amp;quot;&amp;amp;
    # start Emacs
    exec /usr/local/bin/emacs &amp;amp;
else
    # Emacs is already running...
    if [ $win = $(xdotool getwindowfocus) ]; then
        # ...and focused
        # do nothing
        sleep 0.2;
    else
        # switch to it
        xdotool windowactivate $win
    fi
fi&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;You can download &lt;code&gt;compiz-send&lt;/code&gt; from &lt;a href=&quot;http://wiki.compiz.org/Plugins/Dbus?action=AttachFile&amp;amp;do=get&amp;amp;target=compiz-send.py&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So there you have it. At the moment, life is back to Gnome+Compiz. If you know any nifty hacks for Gnome+Compiz, please let me know in the comments.&lt;/p&gt;

&lt;h4&gt;References:&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://wiki.compiz.org/Plugins/Dbus&quot;&gt;wiki.compiz.org&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Reboot.</title>
    <link href="http://vedang.me/weblog/2011/07/30/reboot"/>
    <updated>2011-07-30T14:24:00+05:30</updated>
    <id>http://vedang.me/weblog/2011/07/30/reboot</id>
    <content type="html">&lt;p&gt;Once upon a time I had a blog. Then one day I ran out of motivation, inclination, desire, drive, whatnot to post to that blog. I never really ran out of content though. At least, I think not.&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='/images/garfield.gif' alt=' [This image does not belong to me. It is (probably) copyright Jim Davis or some slimeball corporation. I am not using this image for profit, so please do not sue me. (&quot;Ask him to write a post, he goes &quot;No, Thank you&quot;, but ask him to ramble endlessly in an Alt Text...&quot;)] ' title=' [This image does not belong to me. It is (probably) copyright Jim Davis or some slimeball corporation. I am not using this image for profit, so please do not sue me. (&quot;Ask him to write a post, he goes &quot;No, Thank you&quot;, but ask him to ramble endlessly in an Alt Text...&quot;)] '&gt;&lt;/p&gt;

&lt;p&gt;I worried that I'd drown this world in my drivel, but lately I've come to realise that no one gives a shit. So I'm going to write for the right reasons: Because it makes me happy. Stick around, and I'll try not to bore you. Or leave. I don't give a shit.&lt;/p&gt;
</content>
  </entry>
  
</feed>

