<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2745902209960268626</id><updated>2011-09-04T06:24:32.585-05:00</updated><category term='scheme'/><category term='ffi'/><category term='javascript'/><category term='kdwm'/><category term='plugin'/><category term='contracts'/><category term='erlang'/><category term='crossword'/><category term='bibtex'/><category term='extension'/><category term='haskell'/><category term='plt'/><category term='perl'/><category term='acm'/><category term='template haskell'/><category term='chromium'/><category term='argon'/><category term='pidgin'/><category term='vim'/><category term='dot'/><category term='quick reference'/><category term='graphviz'/><category term='tiling'/><category term='chrome'/><title type='text'>Karl's Hacking Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.bloggish.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-3086831181487009576</id><published>2011-07-25T10:30:00.003-05:00</published><updated>2011-07-25T10:45:30.348-05:00</updated><title type='text'>On File Names</title><content type='html'>&lt;p&gt;Many programs have input languages that they accept. Compilers and
interpreters accept programs, web browsers accept web pages, database
systems accept queries, and file systems accept file names. An input
language can be a great way to get input from a user.&lt;/p&gt;

&lt;p&gt;But programs should not be using these input languages when they
communicate with each other. Why? Because if program A is manipulating
strings in the input language of program B, then A is reimplementing
at least some of the syntactic and semantic logic that is already in
program B. These reimplementations, besides being wasted effort, tend
to be brittle and buggy.&lt;/p&gt;

&lt;p&gt;In some areas, we've made great progress in dealing with this problem.
For example, there are many libraries which allow for the manipulation
of program source code. But there is one input language in particular
whose semantics are at least partially reimplemented by nearly every
substantial program in existence: the language of file names.&lt;/p&gt;

&lt;p&gt;Lest you think that the language of file names is trivial, consider all of these syntactic and semantic details which a robust program must consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relative and absolute paths&lt;/li&gt;
&lt;li&gt;Trailing slashes&lt;/li&gt;
&lt;li&gt;Parent and self references&lt;/li&gt;
&lt;li&gt;Special files (devices, pipes, directories, and symbolic links)&lt;/li&gt;
&lt;li&gt;Hard links&lt;/li&gt;
&lt;li&gt;Permissions (having a file name doesn't mean you can open it)&lt;/li&gt;
&lt;li&gt;Existence (having a file name doesn't mean it exists)&lt;/li&gt;
&lt;li&gt;Platform-specific issues, such as:
&lt;ul&gt;
&lt;li&gt;Supported characters in names&lt;/li&gt;
&lt;li&gt;Special characters (like the path separator)&lt;/li&gt;
&lt;li&gt;Whether or not particular kinds of links are supported&lt;/li&gt;
&lt;li&gt;What permissions are supported&lt;/li&gt;
&lt;li&gt;Oddities like Windows drives&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;Now, I will briefly consider solutions to this problem. Much more about solutions will come in a future post. Two options have come to mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Provide a wrapper interface for existing file systems that understands and enforces all the relevant syntactic and semantic details.&lt;/li&gt;
&lt;li&gt;Provide a fundamentally different file system. This option is more powerful, and I have some ideas about how this power can be used which I will discuss in a future post, hopefully with a prototype implementation of such a file system.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-3086831181487009576?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/3086831181487009576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2011/07/on-file-names.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3086831181487009576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3086831181487009576'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2011/07/on-file-names.html' title='On File Names'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-339036389922966409</id><published>2011-03-02T14:54:00.002-06:00</published><updated>2011-03-02T14:56:47.395-06:00</updated><title type='text'>Read This</title><content type='html'>&lt;p&gt;Read this: &lt;a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html"&gt;&lt;u&gt;On the cruelty of really teaching computing science&lt;/u&gt;&lt;/a&gt; by Edsger W. Dijkstra. Yes, it's a bit long, but it is best read carefully and completely.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-339036389922966409?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/339036389922966409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2011/03/read-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/339036389922966409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/339036389922966409'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2011/03/read-this.html' title='Read This'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-7369568447403315812</id><published>2010-12-07T21:14:00.005-06:00</published><updated>2010-12-11T20:26:56.410-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crossword'/><title type='text'>Frontiers</title><content type='html'>&lt;p&gt;Since I should be doing homework, here's a crossword puzzle: &lt;a href="http://dl.dropbox.com/u/6549070/crossword/Frontiers.pdf"&gt;Frontiers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As usual, I haven't done extensive proofreading: that's what my loyal readers are for. If you find anything that is or might be wrong, &lt;a href="mailto:ktvoelker@gmail.com"&gt;please tell me&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-7369568447403315812?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/7369568447403315812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/12/frontiers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/7369568447403315812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/7369568447403315812'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/12/frontiers.html' title='Frontiers'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-1595231074006925289</id><published>2010-10-30T10:59:00.002-05:00</published><updated>2010-10-30T11:05:12.936-05:00</updated><title type='text'>Announcing Argon 0.2.0</title><content type='html'>&lt;p&gt;I am pleased to announce the release of &lt;a href="http://argon.karlv.net"&gt;Argon 0.2.0&lt;/a&gt;, a declarative tiling window manager.&lt;/p&gt;

&lt;p&gt;This release seems to be fairly solid. I have been using it for a week without any crashes. But, to be fair, my testing of features that I don't regularly use has not been extensive.&lt;/p&gt;

&lt;p&gt;Anyway, Argon is now featureful, usable, and well-documented. Check out &lt;a href="http://argon.karlv.net"&gt;the website&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-1595231074006925289?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/1595231074006925289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/10/announcing-argon-020.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/1595231074006925289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/1595231074006925289'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/10/announcing-argon-020.html' title='Announcing Argon 0.2.0'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-5146456587862194877</id><published>2010-10-10T23:05:00.003-05:00</published><updated>2010-10-10T23:17:51.476-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='extension'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='acm'/><category scheme='http://www.blogger.com/atom/ns#' term='bibtex'/><title type='text'>Un-over-engineering the ACM Digital Library</title><content type='html'>&lt;p&gt;I have a gripe with the ACM Digital Library website. It is too hard to get the BibTeX from an article's page. Now, you might be thinking that I am crazy. After all, the link to the BibTeX is &lt;em&gt;right there&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Well, that link is stupid. Its real target isn't the BibTeX (in fact, it's the citation page you are already on). Thus, you can't right-click and save the BibTeX file directly. Instead, it helpfully opens the BibTeX in a new window via its &lt;tt&gt;onclick&lt;/tt&gt; event handler. And that's actually the same window for every article, so if you find a bunch of articles and click all the BibTeX links thinking you will get something sensible, you actually get one window showing the BibTeX of whatever you clicked on last.&lt;/p&gt;

&lt;p&gt;I have created an alternative. It's not perfect, but it only took about 45 minutes to create, including all the time needed to learn how to make and package an extension for Chrome. What &lt;a href="http://github.com/ktvoelker/chrome-acm-bibtex"&gt;this extension&lt;/a&gt; does is add an inline frame containing the BibTeX so you can copy it to your bibliography database.&lt;/p&gt;

&lt;p&gt;One caveat: the extension is currently hard-coded to work on two domains: &lt;tt&gt;portal.acm.org&lt;/tt&gt; and &lt;tt&gt;portal.acm.org.ezproxy.library.wisc.edu&lt;/tt&gt;. The latter is how I browse ACM from home. I could change this to work more generally (and thus request more permissions upon install), but it already works for me. Go ahead and submit a patch if you want to.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-5146456587862194877?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/5146456587862194877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/10/un-over-engineering-acm-digital-library.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5146456587862194877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5146456587862194877'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/10/un-over-engineering-acm-digital-library.html' title='Un-over-engineering the ACM Digital Library'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-6414702302530925314</id><published>2010-10-04T21:21:00.003-05:00</published><updated>2010-10-04T21:38:54.681-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='argon'/><category scheme='http://www.blogger.com/atom/ns#' term='kdwm'/><title type='text'>Argon</title><content type='html'>&lt;p&gt;Now that the pace of my schoolwork is starting to pick up, I have had less time to work on &lt;a href="http://argon.karlv.net/"&gt;my window manager&lt;/a&gt;. But I have made progress. However, my claim that the first release was usable may have been premature. At least, it wasn't usable to me, and since I am my entire target audience, that is a bit of a problem. So, I will not be making another release until I have actually started using my window manager for my own window-management needs.&lt;/p&gt;

&lt;p&gt;One other accomplishment is that my window manager is longer called "KDWM", which was rather dull. It now has a more exciting name: "Argon". But I didn't &lt;em&gt;only&lt;/em&gt; choose this name because it did well in the focus groups. Argon (the window manager) was originally meant to be "declarative". When I began working on it, I had a few ideas about what that would mean to a window manager, and they all turned out to be wrong. Eventually, I dropped the word from every document&amp;#x2014;except the acronym, where it lived on in the letter "D".&lt;/p&gt;

&lt;p&gt;I have since discovered that Argon is quite declarative indeed, and the new name is intended not only to sound wonderful but also to emphasize that fact. How does it do this? Argon, the element, is one of the noble gases, which means that its electronic configuration is stable enough that it almost never engages in chemical reactions. I want my Argon to exhibit a similar level of stability and predictability.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-6414702302530925314?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/6414702302530925314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/10/argon.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6414702302530925314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6414702302530925314'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/10/argon.html' title='Argon'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-2601194944508862735</id><published>2010-09-18T19:48:00.004-05:00</published><updated>2010-10-04T21:39:52.440-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='argon'/><category scheme='http://www.blogger.com/atom/ns#' term='kdwm'/><title type='text'>Announcing kdwm 0.1.0</title><content type='html'>&lt;p&gt;I am pleased to present the first usable release of KDWM, a window manager that does what I want. My work so far on KDWM has had two purposes: creating a tiling window manager that works exactly the way I want it to, and learning a lot about Haskell and window managers in general.&lt;/p&gt;

&lt;p&gt;If you are just so excited that you want to start using KDWM right now, you can &lt;a href="http://github.com/downloads/ktvoelker/argon/kdwm-0.1.0.tar.gz"&gt;download it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you'd like to browse the source or read the user documentation (which is also included in the download package), visit &lt;a href="http://github.com/ktvoelker/argon"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-2601194944508862735?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/2601194944508862735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/09/announcing-kdwm-010.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/2601194944508862735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/2601194944508862735'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/09/announcing-kdwm-010.html' title='Announcing kdwm 0.1.0'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-6534924202724034242</id><published>2010-09-06T23:32:00.006-05:00</published><updated>2010-09-09T17:11:10.660-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='template haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>"Do Records" for Haskell</title><content type='html'>&lt;p&gt;While working on a parser written with &lt;a href="http://www.haskell.org/haskellwiki/Parsec"&gt;Parsec&lt;/a&gt;, I began to feel annoyed at some repetitious code like this:&lt;/p&gt;

&lt;script src="http://gist.github.com/567867.js?file=gistfile1.hs"&gt;&lt;/script&gt;

&lt;p&gt;This pattern is no doubt common in any Parsec grammar which produces a fairly straightforward AST. As demonstrated, each field of the particular AST node being constructed is mentioned three times. This pain can be reduced somewhat by using terse names for the intermediate bindings, but this detracts from the readability of the code.&lt;/p&gt;

&lt;p&gt;I created a solution to this problem using Template Haskell. The previous example can then be written like this:&lt;/p&gt;

&lt;script src="http://gist.github.com/567872.js?file=gistfile1.html"&gt;&lt;/script&gt;

&lt;p&gt;Take a look at &lt;a href="http://github.com/ktvoelker/do_records/blob/master/DoRecord.hs"&gt;how it works&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-6534924202724034242?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/6534924202724034242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/09/do-records-for-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6534924202724034242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6534924202724034242'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/09/do-records-for-haskell.html' title='&quot;Do Records&quot; for Haskell'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-5062938263372389567</id><published>2010-08-03T13:28:00.003-05:00</published><updated>2010-08-03T14:05:24.616-05:00</updated><title type='text'>Jargon</title><content type='html'>&lt;p&gt;A friend recently shared &lt;a href="http://janeknight.typepad.com/pick/2010/08/how-the-internet-works-infographic.html"&gt;this infographic about how the Internet works&lt;/a&gt; on Google Reader. Go read it first. What struck me about it is how full of unexplained jargon it is, despite the fact that the creator was clearly trying to make something anyone can understand. Just as bad as jargon, the graphic also employs a lot of conceptual jargon: that is, ideas which, without further elaboration, probably seem nonsensical to an outsider.&lt;/p&gt;

&lt;p&gt;In addition to criticism, I will give my suggestions about what could have been said.&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;q&gt;let's try to strip a little of the mystery from this great web&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;Okay, this is not jargon, but it's still a poor choice of words. It may unintentionally further the average person's conflation of "the Internet" and "the world wide web," something which a graphic trying to explain the Internet should want to avoid.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;language&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;Most people have never encountered the concept of a formal language. While formal and human languages share many characteristics, only formal languages are fundamentally useful for inter-computer communication. To use the word "language" without explaining briefly what makes computer languages different is not a good idea. People may end up thinking that the computers are calling each other up on the phone and speaking English. This wouldn't be hard to correct: just say that a computer language tends to have "simple grammatical rules which are rigidly followed."&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;protocol suite&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;The graphic wastes space using and explaining this term, in reference to TCP/IP, when it could have simply said "the Internet relies on two protocols: TCP and IP." The concept of a "protocol suite" is irrelevant to understanding the Internet.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;addresses&lt;/q&gt; and &lt;q&gt;names&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;Here the graphic is using two different analogies simultaneously to explain IP addresses. It would have been better to choose one, with more space devoted to explaining the analogy, since neither one is perfect. In fact, a better analogy than either of these is to say that an IP address is like a phone number. DNS is then simply a phone book. The main difference which must be explained is that when a computer's IP address changes, it's not a big deal, because all the phone books update automatically.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;dynamic&lt;/q&gt; and &lt;q&gt;static addresses&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;This is not truly a black-and-white distinction, nor is it especially important for an understanding of the Internet. It would be better to simply say that some computers' phone numbers change more often than others.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;server&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;This term is used without explanation. If it is going to be used, it would probably be best to explain the client-server model in a bit more detail, before the diagram. You might think this is hard, but it isn't. Just mention that "client" and "server" are two roles a computer can play at any moment. Typically, your computer is a "client," which means it is asking for information, and a "server" somewhere else is providing that information back to you.&lt;/dd&gt;
&lt;dt&gt;that diagram with the arrows&lt;/dt&gt;
&lt;dd&gt;This diagram is very confusing. There's no way to understand from the diagram what order things happen in. You can't easily follow a particular piece of data as it flows through the system. It would have been better (and more informative) to separate the DNS query into another diagram (or simply remove it), since the DNS query is a separate request using a separate connection. Then, the remaining diagram could have truly been done in a data-flow style.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;ones and zeroes&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;Chances are anyone who has enough interest in computers to make it this far down the infographic has already heard this clich&amp;eacute; explanation, but it's not that helpful. How does a person with no technical knowledge even fathom the idea that all information can be turned into ones and zeroes? An example here of that translation would be immensely helpful toward creating understanding. A good (and exciting) example would be to show how a small image can be imagined in pixels, with RGB color values, which can each be represented in binary.&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;host&lt;/q&gt;, &lt;q&gt;megabit&lt;/q&gt;, &lt;q&gt;URL&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;These terms are all used, without explanation, in the bottom portion of the graphic, which is mostly devoted to explaining how huge the Internet is. Besides that, all that explanation of the hugeness is pretty much unrelated to how the Internet works. It would have been better as a separate graphic.&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;I would have created a graphic incorporating all my suggestions, but I am not much of a designer. If you want to, feel free, but please let me suggest edits to the text before you put it online.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-5062938263372389567?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/5062938263372389567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/08/jargon.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5062938263372389567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5062938263372389567'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/08/jargon.html' title='Jargon'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-4345285932467127901</id><published>2010-07-31T20:05:00.003-05:00</published><updated>2010-07-31T20:06:07.219-05:00</updated><title type='text'>Master of Science</title><content type='html'>&lt;p&gt;For those who don't already know, I have completed my M.S. thesis.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://pptf.karlv.net/"&gt;Read more here.&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-4345285932467127901?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/4345285932467127901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/07/master-of-science.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4345285932467127901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4345285932467127901'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/07/master-of-science.html' title='Master of Science'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-5410823855673103176</id><published>2010-07-22T10:55:00.012-05:00</published><updated>2010-10-04T21:20:58.826-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='template haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>Adventures in Template Haskell</title><content type='html'>&lt;p&gt;I've been working on &lt;a href="http://github.com/ktvoelker/argon"&gt;a window manager&lt;/a&gt; lately, but this post isn't about that. Perhaps a later one will be.&lt;/p&gt;

&lt;p&gt;In the course of this work, I stumbled across a sort of gap in what you can easily do with Haskell's record syntax:&lt;/p&gt;

&lt;script src="http://gist.github.com/503567.js?file=gistfile1.hs"&gt;&lt;/script&gt;

&lt;p&gt;Basically, getting an updated record where a function has been applied to a particular field involves naming the field and the record twice. The longer the names, the worse it gets. I solved this problem with some Template Haskell:&lt;/p&gt;

&lt;script src="http://gist.github.com/503567.js?file=gistfile2.hs"&gt;&lt;/script&gt;

&lt;p&gt;It gets even better when the record you are updating is the state of a &lt;tt&gt;State&lt;/tt&gt; monad:&lt;/p&gt;

&lt;script src="http://gist.github.com/503567.js?file=gistfile3.hs"&gt;&lt;/script&gt;

&lt;p&gt;Since the record doesn't need to be named, the lambda is avoided.&lt;/p&gt;

&lt;p&gt;Take a look at &lt;a href="http://github.com/ktvoelker/argon/blob/master/src/Fields.hs"&gt;the code&lt;/a&gt; to see how it works.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-5410823855673103176?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/5410823855673103176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/07/adventures-in-template-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5410823855673103176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5410823855673103176'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/07/adventures-in-template-haskell.html' title='Adventures in Template Haskell'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-1221603068101309746</id><published>2010-07-15T20:17:00.006-05:00</published><updated>2010-08-01T12:47:47.813-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>A Safe and Improved Replacement for vim Modelines</title><content type='html'>&lt;p&gt;If you work on multiple projects which have different source code formatting conventions, vim's modelines can be useful. They allow a file to specify vim options which should be set when that file is loaded, such as options relating to the treatment of tabs. However, enabling modelines can be risky if you are editing files written by other people. Furthermore, maintaining a particular modeline across all the source files in a project is an aggravating but necessary task.&lt;/p&gt;

&lt;p&gt;Today I wrote a little solution to this problems which I call "dirmode". It is a vim plugin which provides a feature somewhat like modelines, except that the options are stored in a separate file and affect all files in the directory where the options file is located.&lt;/p&gt;

&lt;p&gt;The plugin is already usable and useful, albeit under-documented. I do have plans for some improvements, which you can read about &lt;a href="http://github.com/ktvoelker/vim-dirmode/blob/master/todo"&gt;in my to-do list&lt;/a&gt;. Also, have a look at &lt;a href="http://github.com/ktvoelker/vim-dirmode"&gt;the source&lt;/a&gt; if you are interested.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-1221603068101309746?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/1221603068101309746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/07/safe-and-improved-replacement-for-vim.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/1221603068101309746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/1221603068101309746'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/07/safe-and-improved-replacement-for-vim.html' title='A Safe and Improved Replacement for vim Modelines'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-7341734298684145797</id><published>2010-07-08T16:07:00.006-05:00</published><updated>2010-08-01T12:47:54.572-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crossword'/><title type='text'>Flowing</title><content type='html'>&lt;p&gt;Here is the other crossword puzzle produced by my camping trip, &lt;a href="http://dl.dropbox.com/u/6549070/crossword/Flowing.pdf"&gt;Flowing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I realized today that a few words in this puzzle which seemed real out in the wilderness turned out to be somewhat imaginary. With the help of modern technology, I managed to replace those words without disrupting everything else too badly.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-7341734298684145797?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/7341734298684145797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/07/flowing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/7341734298684145797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/7341734298684145797'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/07/flowing.html' title='Flowing'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-5278008048945867105</id><published>2010-07-07T23:21:00.005-05:00</published><updated>2010-08-01T12:47:59.779-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crossword'/><title type='text'>Urbanism</title><content type='html'>&lt;p&gt;Here is another crossword puzzle, &lt;a href="http://dl.dropbox.com/u/6549070/crossword/Urbanism.pdf"&gt;Urbanism&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am aware that this puzzle does not quite follow the conventions which I have been striving for: it contains a slight asymmetry and a single two-letter word. I don't think it's much of a problem. I would like to experiment with some "non-traditional" shapes, which will probably be even less symmetrical.&lt;/p&gt;

&lt;p&gt;Unlike my previous puzzles, this puzzle grid was constructed without any electronic aids. I like the result better because the words feel more personal. But, I was more deliberate about using the black space to keep different parts of the puzzle fairly separate. I don't know if I could make a puzzle with Harry Truman's level of openness without some computerized help.&lt;/p&gt;

&lt;p&gt;Another puzzle will be out soon. I made two grids on my recent trip into the wilderness, but I haven't written any clues for the second one.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-5278008048945867105?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/5278008048945867105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/07/urbanism.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5278008048945867105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/5278008048945867105'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/07/urbanism.html' title='Urbanism'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-9175366411472033791</id><published>2010-06-28T01:38:00.005-05:00</published><updated>2010-08-01T12:48:04.676-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crossword'/><title type='text'>Harry Truman</title><content type='html'>&lt;p&gt;After watching &lt;a href="http://www.imdb.com/title/tt0492506/"&gt;Wordplay&lt;/a&gt;, I was inspired to try making a crossword puzzle again. &lt;a href="http://dl.dropbox.com/u/6549070/crossword/Harry_Truman.pdf"&gt;Here it is.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; I fixed a typo in 44-Across. Also, the puzzle has been re-typeset in a slightly better fashion. (This came about as the result of automating the entire typesetting process. Maybe I should write about how that works.)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-9175366411472033791?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/9175366411472033791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/06/harry-truman.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/9175366411472033791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/9175366411472033791'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/06/harry-truman.html' title='Harry Truman'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-360360399035710000</id><published>2010-06-05T23:09:00.006-05:00</published><updated>2010-08-01T12:48:43.412-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tiling'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='pidgin'/><title type='text'>Pidgin with Less Windows</title><content type='html'>&lt;p&gt;I use &lt;a href='http://www.pidgin.im/'&gt;Pidgin&lt;/a&gt; for my instant messaging, but I also use a tiling window manager. Getting the conversation window to appear in the right place is a tricky problem. After years of horrible kludges, I finally got around to solving this problem the right way: by changing Pidgin to make new conversation tabs appear inside the Buddy List window. So, I just have to put that window in the right place &lt;em&gt;once&lt;/em&gt;, and all (one of) my pidgin windows are in the right place all the time.&lt;/p&gt;

&lt;p&gt;Now, I am not a Pidgin developer. I've never even made a Pidgin plugin until tonight. So, the pre-pre-alpha-quality code which I'm revealing here is about as much of a horrible kludge as all my previous window manager tricks. But, this kludge works better than all the previous ones, so I'm sticking with it, and I'll get the code cleaned up over time.&lt;/p&gt;

&lt;p&gt;By the way, there is &lt;a href='http://developer.pidgin.im/ticket/5782'&gt;a two-year-old enhancement request for this feature on the Pidgin Trac&lt;/a&gt;. The approach suggested in the comment there by deryni is the approach I used, and it seems to work fine.&lt;/p&gt;

&lt;p&gt;So what is that approach? First, there is a plugin. Pretty much all the functionality is in the plugin (but not quite, because I needed to extern some functions that used to be private to the conversation window module, and I made a slight addition to the heirarchy of GTK containers inside the Buddy List window). So, in order to use this plugin, you actually need to build the entire &lt;a href='http://www.pidgin.im/download/source/'&gt;Pidgin source tree&lt;/a&gt; with my patches.&lt;/p&gt;

&lt;p&gt;Oh yeah, my patches. &lt;a href='http://github.com/ktvoelker/pidgin-onewin'&gt;Here they are.&lt;/a&gt; There are two files in there that you need. &lt;tt&gt;patch&lt;/tt&gt; is a diff of my changes to the main Pidgin source tree. &lt;tt&gt;onewin.c&lt;/tt&gt; is the plugin source. Put it in &lt;tt&gt;$PIDGIN/pidgin/plugins&lt;/tt&gt;, and once you've built the Pidgin source, go into &lt;tt&gt;$PIDGIN/pidgin/plugins&lt;/tt&gt; and run &lt;tt&gt;make onewin.so&lt;/tt&gt; to build the plugin. Then copy &lt;tt&gt;onewin.so&lt;/tt&gt; into &lt;tt&gt;~/.purple/plugins&lt;/tt&gt;. (Note: it seems that you can't just run the pidgin binary from the source tree, because it can't find some important modules, like the IM protocol handlers.)&lt;/p&gt;

&lt;p&gt;One more step is required for the plugin to work, but first I will digress a bit into its implementation. Pidgin has a concept called "conversation placement functions." There are a bunch of default placement functions which provide behavior like "one conversation per window" or "all conversations in one window." My plugin provides a new conversation placement function called "&lt;tt&gt;onewin&lt;/tt&gt;" that puts conversations inside the Buddy List window. In order for my plugin to actually do anything, though, Pidgin has to decide to use the &lt;tt&gt;onewin&lt;/tt&gt; placement function. I haven't yet figured out how to do that in any reasonable way, so I just edited &lt;tt&gt;~/.purple/prefs.xml&lt;/tt&gt; so that &lt;tt&gt;/purple/conversations/placement&lt;/tt&gt; was set to &lt;tt&gt;onewin&lt;/tt&gt;. (You also need to have the plugin enabled. Right now, it will show up in your plugin list as "Hello World" because I haven't changed its name. I'm not sure what happens if you try to use &lt;tt&gt;onewin&lt;/tt&gt; when the plugin isn't enabled.)&lt;/p&gt;

&lt;p&gt;There are some known issues with the plugin. You can look at my &lt;a href='http://github.com/ktvoelker/pidgin-onewin/blob/master/todo'&gt;to-do list&lt;/a&gt; if you are interested.&lt;/p&gt;

&lt;p&gt;There are also a lot of unknown issues with the plugin. If you find any of them, &lt;a href='mailto:ktvoelker@gmail.com'&gt;please tell me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, I will note that I am building and testing this on Arch Linux i686. I think it should build on any platform where Pidgin builds, but I'm not going to try it. If you do, I'd like to hear about it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-360360399035710000?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/360360399035710000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/06/pidgin-with-less-windows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/360360399035710000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/360360399035710000'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/06/pidgin-with-less-windows.html' title='Pidgin with Less Windows'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-4339428772918418720</id><published>2010-03-21T00:43:00.009-05:00</published><updated>2010-08-01T12:48:51.152-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>Geometric Series in Haskell Using [..] Notation</title><content type='html'>&lt;p&gt;I was reading the docs earlier today for Haskell's &lt;tt&gt;Enum&lt;/tt&gt; class. Any instance of &lt;tt&gt;Enum&lt;/tt&gt; can be used in the &lt;tt&gt;[..]&lt;/tt&gt; notation, which has four forms: &lt;tt&gt;[a..b]&lt;/tt&gt;, &lt;tt&gt;[a,b..c]&lt;/tt&gt;, &lt;tt&gt;[a..]&lt;/tt&gt;, and &lt;tt&gt;[a,b..]&lt;/tt&gt;. The implementor of &lt;tt&gt;Enum a&lt;/tt&gt; can make these forms do anything, so long as they produce a value of type &lt;tt&gt;[a]&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;It occurred to me that I could create a type, and a corresponding &lt;tt&gt;Enum&lt;/tt&gt; instance, which would make the &lt;tt&gt;[..]&lt;/tt&gt; notation produce a geometric series rather than the usual arithmetic series. I called this type &lt;tt&gt;Geo&lt;/tt&gt;. I also made an instance &lt;tt&gt;Integral Geo&lt;/tt&gt; so that the &lt;tt&gt;[Geo]&lt;/tt&gt; could be turned into a list of more usable numeric type. But I didn't stop there, because using the type directly would be ugly: &lt;tt&gt;map toInteger ([1,2..16] :: [Geo])&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;So, I made a function &lt;tt&gt;geo :: (Integral a) =&gt; [Geo] -&gt; [a]&lt;/tt&gt;. So now, to get a geometric series in a reasonable type, the user only had to say &lt;tt&gt;geo [1,2..16]&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Then I realized that, unlike when generating an arithmetic series, integral inputs do not guarantee integral outputs. So, I changed the type &lt;tt&gt;Geo&lt;/tt&gt; to be an instance of &lt;tt&gt;Fractional&lt;/tt&gt; rather than &lt;tt&gt;Integral&lt;/tt&gt;, so that you can do things like &lt;tt&gt;take 5 $ geo [2,1..]&lt;/tt&gt; and get the right answer.&lt;/p&gt;

&lt;p&gt;If you want more detail, &lt;a href='mailto:ktvoelker@gmail.com'&gt;ask me&lt;/a&gt; or &lt;a href='http://github.com/ktvoelker/geometric'&gt;take a look at the code&lt;/a&gt;. An example progam is included.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-4339428772918418720?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/4339428772918418720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2010/03/geometric-series-in-haskell-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4339428772918418720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4339428772918418720'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2010/03/geometric-series-in-haskell-using.html' title='Geometric Series in Haskell Using [..] Notation'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-3195121113617154483</id><published>2009-03-19T18:04:00.011-05:00</published><updated>2010-08-01T12:49:25.038-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphviz'/><category scheme='http://www.blogger.com/atom/ns#' term='dot'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Erdot</title><content type='html'>&lt;p&gt;It occurred to me that I could write &lt;a href="http://en.wikipedia.org/wiki/Entity-relationship_model"&gt;Entity-Relationship diagrams&lt;/a&gt; using &lt;a href="http://www.graphviz.org/"&gt;Graphviz&lt;/a&gt;, but I knew it would be clunky. I created a quick bit of Perl to translate a simple ER description language into Graphviz code, which I have called &lt;a href="http://github.com/ktvoelker/erdot"&gt;Erdot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;entity foo
entity bar
entity baz attr a b c

weak entity quux

relate abc foo bar!*
relate def bar* baz* attr z

relate manages foo&amp;lt;manager&gt; foo&amp;lt;subordinate&gt;

weak relate ghi baz quux&lt;/pre&gt;
&lt;p&gt;becomes:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_NLlQIF2ye50/ScLRKGgbylI/AAAAAAAAAOc/48Cg_sKL7-E/s1600-h/output.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 208px;" src="http://4.bp.blogspot.com/_NLlQIF2ye50/ScLRKGgbylI/AAAAAAAAAOc/48Cg_sKL7-E/s400/output.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5315040481726155346" /&gt;&lt;/a&gt;

&lt;p&gt;Current issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The heirarchical layout used by &lt;tt&gt;dot&lt;/tt&gt; is not much like the layout of a typical hand-drawn diagram. Other layout engines included with Graphviz provide a better layout, but fail to correctly handle edge labels. There might be a way to configure one of those engines to avoid drawing the edge labels on top of everything else (and each other).&lt;/li&gt;
&lt;li&gt;The script could be much more powerful if the ER descriptions were parsed with a CFG instead of a quick hack. Maybe I will take this as an opportunity to learn about the grammar system in Perl 6.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-3195121113617154483?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/3195121113617154483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2009/03/erdot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3195121113617154483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3195121113617154483'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2009/03/erdot.html' title='Erdot'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_NLlQIF2ye50/ScLRKGgbylI/AAAAAAAAAOc/48Cg_sKL7-E/s72-c/output.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-3991505838557209296</id><published>2008-12-08T21:26:00.006-06:00</published><updated>2010-08-01T12:49:37.688-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quick reference'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Erlang Quick Reference</title><content type='html'>&lt;p&gt;Here is an Erlang Quick Reference I just made. I am basically a beginner at Erlang, so I'm not sure if I've covered the right bases or covered them correctly. Suggestions and corrections are welcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://dl.dropbox.com/u/6549070/erlang_ref.pdf'&gt;Erlang Quick Reference (PDF, 24K)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://dl.dropbox.com/u/6549070/erlang_ref.ods'&gt;Erlang Quick Reference (ODS, 32K)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-3991505838557209296?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/3991505838557209296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2008/12/erlang-quick-reference.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3991505838557209296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/3991505838557209296'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2008/12/erlang-quick-reference.html' title='Erlang Quick Reference'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-4539904262445768991</id><published>2008-12-07T03:55:00.006-06:00</published><updated>2010-08-01T12:57:23.704-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='contracts'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Module contracts in Perl</title><content type='html'>&lt;p&gt;I whipped up a little Perl module which foists a contract upon a subroutine. It replaces that subroutine with one which checks the arguments and return value against a predicate. The predicates themselves conform to a simple interface: they must be able to check a value, returning true or false, and they must be able to describe themselves. The latter enables the contract system to provide helpful error messages when a violation occurs.&lt;/p&gt;
&lt;p&gt;Here is an example use of the module:&lt;/p&gt;
&lt;script src="http://gist.github.com/503578.js?file=contracts.pl"&gt;&lt;/script&gt;
&lt;p&gt;The &lt;tt&gt;contract&lt;/tt&gt; function takes three arguments: the name of the subroutine (which must be in the package you are calling from), the predicate for the argument list, and the predicate for the return value. Contract::Predicate exports some predefined predicates as well as the means to create new ones.&lt;/p&gt;
&lt;p&gt;In the example, the call to &lt;tt&gt;foo&lt;/tt&gt; results in a violation, because the function does not return an integer as the contract requires.&lt;/p&gt;
&lt;p&gt;Interesting tidbits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the contract system calls the original function which it has replaced, that call needs to be done in the proper context (array, scalar, or void). AFAIK, you cannot do a call in void context and get the return value of that call. If a function with a contract is called in a void context, the return value contract is not checked. My guess is that this won't matter much in practice. Then again, many subroutines should only be called in certain contexts, so perhaps in addition to the return value predicate, &lt;tt&gt;contract&lt;/tt&gt; should accept some indication of which contexts the function may be legally called in.&lt;/li&gt;
&lt;li&gt;Replacing the functions is done with &lt;tt&gt;Sub::Override&lt;/tt&gt;, which is not a part of the base Perl distribution. It is on CPAN and exists as a Debian package (&lt;tt&gt;libsub-override-perl&lt;/tt&gt;). This module isn't strictly necessary, but I couldn't get it to work the old-fashioned way. (I also didn't spend much time trying.) One interesting feature of &lt;tt&gt;Sub::Override&lt;/tt&gt; which makes it bad for this particular application, but which is a neat idea in general, is that when you do an override, you get back an object, and that object's destructor undoes the override. Consequently, &lt;tt&gt;Contract&lt;/tt&gt; has an internal list of &lt;tt&gt;Sub::Override&lt;/tt&gt; objects which it has to keep around forever.&lt;/li&gt;
&lt;li&gt;I ought to get an account on CPAN and put this up there. I wonder if there are other modules like it? Even if there's a better one, writing this was a quick, fun exercise.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can &lt;a href="http://github.com/ktvoelker/perl-contract"&gt;get the source&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-4539904262445768991?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/4539904262445768991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2008/12/module-contracts-in-perl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4539904262445768991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/4539904262445768991'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2008/12/module-contracts-in-perl.html' title='Module contracts in Perl'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2745902209960268626.post-6169794420940235282</id><published>2008-12-06T04:48:00.003-06:00</published><updated>2010-08-01T12:58:16.142-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ffi'/><category scheme='http://www.blogger.com/atom/ns#' term='plt'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>FFI in PLT Scheme</title><content type='html'>&lt;p&gt;This is way too easy:&lt;/p&gt;
&lt;script src="http://gist.github.com/503580.js?file=ffi.scm"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2745902209960268626-6169794420940235282?l=www.bloggish.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.bloggish.net/feeds/6169794420940235282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.bloggish.net/2008/12/ffi-in-plt-scheme.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6169794420940235282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2745902209960268626/posts/default/6169794420940235282'/><link rel='alternate' type='text/html' href='http://www.bloggish.net/2008/12/ffi-in-plt-scheme.html' title='FFI in PLT Scheme'/><author><name>Karl Voelker</name><uri>http://www.blogger.com/profile/13322149624051995257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://4.bp.blogspot.com/_NLlQIF2ye50/S9owMaaa-AI/AAAAAAAAAPo/0Bv3zNBpwQg/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
