<?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-1563623855220143059</id><updated>2012-02-16T12:28:02.299-08:00</updated><category term='slides'/><category term='debugging'/><category term='latex'/><category term='continuations'/><category term='detrospector'/><category term='assembly'/><category term='types'/><category term='ghc'/><category term='yices-easy'/><category term='quasicrystal'/><category term='hackathon'/><category term='compsci'/><category term='lambda-calculus'/><category term='markdown'/><category term='systems'/><category term='haskell'/><category term='smt'/><category term='tracepoints'/><category term='global-lock'/><category term='code'/><category term='clogparse'/><category term='propane'/><category term='preprocessor'/><category term='mit'/><category term='pandoc'/><category term='phosphene'/><category term='hardware'/><category term='pi-calculus'/><category term='imadethis'/><category term='gdb'/><category term='breakfast'/><category term='security'/><category term='6.S184'/><category term='random'/><category term='graphics'/><category term='debug-diff'/><category term='cabal'/><category term='jvf2010a'/><category term='concurrency'/><category term='type-theory'/><category term='shqq'/><category term='c'/><category term='rts'/><category term='tsp'/><category term='jspath'/><category term='generics'/><category term='kernel'/><category term='hdis86'/><category term='compose'/><category term='repa'/><category term='computability'/><category term='donttrythisathome'/><category term='crystalfontz'/><category term='boston'/><category term='cxx'/><category term='concorde'/><category term='safe-globals'/><title type='text'>main is usually a function</title><subtitle type='html'>char* main = "usually a programming blog";</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-6031546447791889885</id><published>2012-02-14T01:26:00.000-08:00</published><updated>2012-02-14T01:26:15.502-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='donttrythisathome'/><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='continuations'/><title type='text'>Continuations in C++ with fork</title><content type='html'>&lt;p&gt;While reading &amp;quot;&lt;a href="http://homepage.mac.com/sigfpe/Computing/continuations.html"&gt;Continuations in C&lt;/a&gt;&amp;quot; I came across an intriguing idea:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;It is possible to simulate &lt;code&gt;call/cc&lt;/code&gt;, or something like it, on Unix systems with system calls like &lt;code&gt;fork()&lt;/code&gt; that literally duplicate the running process.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The author sets this idea aside, and instead discusses some code that uses &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man3/setjmp.3.html"&gt;&lt;code&gt;setjmp&lt;/code&gt;&lt;/a&gt;/&lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man3/longjmp.3.html"&gt;&lt;code&gt;longjmp&lt;/code&gt;&lt;/a&gt; and stack copying. And there are several other &lt;a href="http://en.wikipedia.org/wiki/Continuation"&gt;continuation&lt;/a&gt;-like constructs available for C, such as POSIX &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/getcontext.2.html"&gt;&lt;code&gt;getcontext&lt;/code&gt;&lt;/a&gt;. But the idea of implementing &lt;a href="http://en.wikipedia.org/wiki/Call-with-current-continuation"&gt;&lt;code&gt;call/cc&lt;/code&gt;&lt;/a&gt; with &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/fork.2.html"&gt;&lt;code&gt;fork&lt;/code&gt;&lt;/a&gt; stuck with me, if only for its amusement value. I'd seen &lt;code&gt;fork&lt;/code&gt; used for &lt;a href="http://okmij.org/ftp/continuations/shift-v-fork.html#implementation-C"&gt;computing with probability distributions&lt;/a&gt;, but I couldn't find an implementation of &lt;code&gt;call/cc&lt;/code&gt; itself. So I decided to give it a shot, using my favorite &lt;a href="http://esoteric.voxelperfect.net/wiki/Main_Page"&gt;esolang&lt;/a&gt;, C++.&lt;/p&gt;&lt;p&gt;Continuations are a famously mind-bending idea, and this article doesn't totally explain what they are or what they're good for. If you aren't familiar with continuations, you might catch on from the examples, or you might want to consult another source first (&lt;a href="http://en.wikipedia.org/wiki/Continuation"&gt;1&lt;/a&gt;, &lt;a href="http://www.madore.org/~david/computers/callcc.html"&gt;2&lt;/a&gt;, &lt;a href="http://community.schemewiki.org/?call-with-current-continuation"&gt;3&lt;/a&gt;, &lt;a href="http://community.schemewiki.org/?call-with-current-continuation-for-C-programmers"&gt;4&lt;/a&gt;, &lt;a href="http://www.ps.uni-saarland.de/~duchier/python/continuations.html"&gt;5&lt;/a&gt;, &lt;a href="http://web.mit.edu/alexmv/6.S184/l7-continuations.pdf"&gt;6&lt;/a&gt;).&lt;/p&gt;&lt;h1 id="small-examples"&gt;Small examples&lt;/h1&gt;&lt;p&gt;I'll get to the implementation later, but right now let's see what these &lt;code&gt;fork&lt;/code&gt;-based continuations can do. The interface looks like this.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &amp;lt;&lt;span class="kw"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span class="kw"&gt;class&lt;/span&gt; cont {&lt;br /&gt;&lt;span class="kw"&gt;public&lt;/span&gt;:&lt;br /&gt;    &lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="kw"&gt;operator&lt;/span&gt;()(&lt;span class="dt"&gt;const&lt;/span&gt; T &amp;amp;x);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &amp;lt;&lt;span class="kw"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;T call_cc( std::function&amp;lt; T (cont&amp;lt;T&amp;gt;) &amp;gt; f );&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://en.cppreference.com/w/cpp/utility/functional/function"&gt;&lt;code&gt;std::function&lt;/code&gt;&lt;/a&gt; is a wrapper that can hold function-like values, such as function objects or C-style function pointers. So &lt;code&gt;call_cc&amp;lt;T&amp;gt;&lt;/code&gt; will accept any function-like value that takes an argument of type &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; and returns a value of type &lt;code&gt;T&lt;/code&gt;. This wrapper is the first of several &lt;a href="http://en.wikipedia.org/wiki/C%2B%2B11"&gt;C++11&lt;/a&gt; features we'll use.&lt;/p&gt;&lt;p&gt;&lt;code&gt;call_cc&lt;/code&gt; stands for &amp;quot;call with current continuation&amp;quot;, and that's exactly what it does. &lt;code&gt;call_cc(f)&lt;/code&gt; will call &lt;code&gt;f&lt;/code&gt;, and return whatever &lt;code&gt;f&lt;/code&gt; returns. The interesting part is that it passes to &lt;code&gt;f&lt;/code&gt; an instance of our &lt;code&gt;cont&lt;/code&gt; class, which represents all the stuff that's going to happen in the program after &lt;code&gt;f&lt;/code&gt; returns. That &lt;code&gt;cont&lt;/code&gt; object overloads &lt;code&gt;operator()&lt;/code&gt; and so can be called like a function. If it's called with some argument &lt;code&gt;x&lt;/code&gt;, the program behaves as though &lt;code&gt;f&lt;/code&gt; had returned &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The types reflect this usage. The type parameter &lt;code&gt;T&lt;/code&gt; in &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; is the return type of the function passed to &lt;code&gt;call_cc&lt;/code&gt;. It's also the type of values accepted by &lt;code&gt;cont&amp;lt;T&amp;gt;::operator()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Here's a small example.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;int&lt;/span&gt; f(cont&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; k) {&lt;br /&gt;    std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;f called&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    k(&lt;span class="dv"&gt;1&lt;/span&gt;);&lt;br /&gt;    std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;k returns&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; main() {&lt;br /&gt;    std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;f returns &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; call_cc&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(f) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When we run this code we get:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;f called&lt;br /&gt;f returns 1&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We don't see the &amp;quot;&lt;code&gt;k returns&lt;/code&gt;&amp;quot; message. Instead, calling &lt;code&gt;k(1)&lt;/code&gt; bails out of &lt;code&gt;f&lt;/code&gt; early, and forces it to return 1. This would happen even if we passed &lt;code&gt;k&lt;/code&gt; to some deeply nested function call, and invoked it there.&lt;/p&gt;&lt;p&gt;This nonlocal return is kind of like throwing an exception, and is not that surprising. More exciting things happen if a continuation outlives the function call it came from.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;boost::optional&amp;lt; cont&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; &amp;gt; global_k;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; g(cont&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt; k) {&lt;br /&gt;    std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;g called&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    global_k = k;&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; main() {&lt;br /&gt;    std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;g returns &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; call_cc&amp;lt;&lt;span class="dt"&gt;int&lt;/span&gt;&amp;gt;(g) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (global_k)&lt;br /&gt;        (*global_k)(&lt;span class="dv"&gt;1&lt;/span&gt;);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When we run this, we get:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;g called&lt;br /&gt;g returns 0&lt;br /&gt;g returns 1&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;g&lt;/code&gt; is called once, and returns twice! When called, &lt;code&gt;g&lt;/code&gt; saves the current continuation in a global variable. After &lt;code&gt;g&lt;/code&gt; returns, &lt;code&gt;main&lt;/code&gt; calls that continuation, and &lt;code&gt;g&lt;/code&gt; returns again with a different value.&lt;/p&gt;&lt;p&gt;What value should &lt;code&gt;global_k&lt;/code&gt; have before &lt;code&gt;g&lt;/code&gt; is called? There's no such thing as a &amp;quot;default&amp;quot; or &amp;quot;uninitialized&amp;quot; &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt;. We solve this problem by wrapping it with &lt;a href="http://www.boost.org/libs/optional/index.html"&gt;&lt;code&gt;boost::optional&lt;/code&gt;&lt;/a&gt;. We use the resulting object much like a pointer, checking for &amp;quot;null&amp;quot; and then dereferencing. The difference is that &lt;code&gt;boost::optional&lt;/code&gt; manages storage for the underlying value, if any.&lt;/p&gt;&lt;p&gt;Why isn't this code an infinite loop? Because &lt;strong&gt;invoking a &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; also resets global state&lt;/strong&gt; to the values it had when the continuation was captured. The second time &lt;code&gt;g&lt;/code&gt; returns, &lt;code&gt;global_k&lt;/code&gt; has been reset to the &amp;quot;null&amp;quot; &lt;code&gt;optional&lt;/code&gt; value. This is &lt;strong&gt;unlike Scheme's &lt;code&gt;call/cc&lt;/code&gt; and most other continuation systems&lt;/strong&gt;. It turns out to be a serious limitation, though it's sometimes convenient. The reason for this behavior is that invoking a continuation is implemented as a transfer of control to another process. More on that later.&lt;/p&gt;&lt;h1 id="backtracking"&gt;Backtracking&lt;/h1&gt;&lt;p&gt;We can use continuations to implement backtracking, as found in &lt;a href="http://en.wikipedia.org/wiki/Logic_programming"&gt;logic programming&lt;/a&gt; languages. Here is a suitable interface.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;bool&lt;/span&gt; guess();&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; fail();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will use &lt;code&gt;guess&lt;/code&gt; as though it has a magical ability to predict the future. We assume it will only return &lt;code&gt;true&lt;/code&gt; if doing so results in a program that never calls &lt;code&gt;fail&lt;/code&gt;. Here is the implementation.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;boost::optional&amp;lt; cont&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; &amp;gt; checkpoint;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;bool&lt;/span&gt; guess() {&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; call_cc&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt;( [](cont&amp;lt;&lt;span class="dt"&gt;bool&lt;/span&gt;&amp;gt; k) {&lt;br /&gt;        checkpoint = k;&lt;br /&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;true&lt;/span&gt;;&lt;br /&gt;    } );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; fail() {&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (checkpoint) {&lt;br /&gt;        (*checkpoint)(&lt;span class="kw"&gt;false&lt;/span&gt;);&lt;br /&gt;    } &lt;span class="kw"&gt;else&lt;/span&gt; {&lt;br /&gt;        std::cerr &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;Nothing to be done.&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;        exit(&lt;span class="dv"&gt;1&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;guess&lt;/code&gt; invokes &lt;code&gt;call_cc&lt;/code&gt; on a &lt;a href="http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B"&gt;lambda expression&lt;/a&gt;, which saves the current continuation and returns &lt;code&gt;true&lt;/code&gt;. A subsequent call to &lt;code&gt;fail&lt;/code&gt; will invoke this continuation, retrying execution in a world where &lt;code&gt;guess&lt;/code&gt; had returned &lt;code&gt;false&lt;/code&gt; instead. In Scheme et al, we would store a whole stack of continuations. But invoking our &lt;code&gt;cont&amp;lt;bool&amp;gt;&lt;/code&gt; resets global state, including the &lt;code&gt;checkpoint&lt;/code&gt; variable itself, so we only need to explicitly track the most recent continuation.&lt;/p&gt;&lt;p&gt;Now we can implement the integer factoring example from &amp;quot;&lt;a href="http://homepage.mac.com/sigfpe/Computing/continuations.html"&gt;Continuations in C&lt;/a&gt;&amp;quot;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;int&lt;/span&gt; integer(&lt;span class="dt"&gt;int&lt;/span&gt; m, &lt;span class="dt"&gt;int&lt;/span&gt; n) {&lt;br /&gt;    &lt;span class="kw"&gt;for&lt;/span&gt; (&lt;span class="dt"&gt;int&lt;/span&gt; i=m; i&amp;lt;=n; i++) {&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (guess())&lt;br /&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; i;&lt;br /&gt;    }&lt;br /&gt;    fail();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; factor(&lt;span class="dt"&gt;int&lt;/span&gt; n) {&lt;br /&gt;    &lt;span class="dt"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; i = integer(&lt;span class="dv"&gt;2&lt;/span&gt;, &lt;span class="dv"&gt;100&lt;/span&gt;);&lt;br /&gt;    &lt;span class="dt"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; j = integer(&lt;span class="dv"&gt;2&lt;/span&gt;, &lt;span class="dv"&gt;100&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (i*j != n)&lt;br /&gt;        fail();&lt;br /&gt;&lt;br /&gt;    std::cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot; * &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; j &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot; = &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; std::endl;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;factor(n)&lt;/code&gt; will guess two integers, and fail if their product is not &lt;code&gt;n&lt;/code&gt;. Calling &lt;code&gt;factor(391)&lt;/code&gt; will produce the output&lt;/p&gt;&lt;pre&gt;&lt;code&gt;17 * 23 = 391&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;after a moment's delay. In fact, you might see this &lt;em&gt;after&lt;/em&gt; your shell prompt has returned, because the output is produced by a thousand-generation descendant of the process your shell created.&lt;/p&gt;&lt;h1 id="solving-a-maze"&gt;Solving a maze&lt;/h1&gt;&lt;p&gt;For a more substantial use of backtracking, let's solve a maze.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; maze_size = &lt;span class="dv"&gt;15&lt;/span&gt;;&lt;br /&gt;&lt;span class="dt"&gt;char&lt;/span&gt; maze[] =&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;X-------------+&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;        |     |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|--+  | |   | |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|  |  | | --+ |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|     |     | |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|-+---+--+- | |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;| |      |    |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;| | | ---+-+- |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|   |      |  |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;| +-+-+--|    |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;| |   |  |--- |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|     |       |&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|--- -+-------|&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;|              &lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="st"&gt;&amp;quot;+------------- &lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; solve_maze() {&lt;br /&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; x=&lt;span class="dv"&gt;0&lt;/span&gt;, y=&lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;while&lt;/span&gt; ((x != maze_size&lt;span class="dv"&gt;-1&lt;/span&gt;)&lt;br /&gt;        || (y != maze_size&lt;span class="dv"&gt;-1&lt;/span&gt;)) {&lt;br /&gt;&lt;br /&gt;             &lt;span class="kw"&gt;if&lt;/span&gt; (guess()) x++;&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; (guess()) x--;&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; (guess()) y++;&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt;              y--;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (  (x &amp;lt; &lt;span class="dv"&gt;0&lt;/span&gt;) || (x &amp;gt;= maze_size) ||&lt;br /&gt;              (y &amp;lt; &lt;span class="dv"&gt;0&lt;/span&gt;) || (y &amp;gt;= maze_size)  )&lt;br /&gt;            fail();&lt;br /&gt;&lt;br /&gt;        &lt;span class="dt"&gt;const&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; i = y*(maze_size&lt;span class="dv"&gt;+1&lt;/span&gt;) + x;&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (maze[i] != ' ')&lt;br /&gt;            fail();&lt;br /&gt;        maze[i] = 'X';&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;for&lt;/span&gt; (&lt;span class="dt"&gt;char&lt;/span&gt; c : maze) {&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (c == 'X')&lt;br /&gt;            std::cout &amp;lt;&amp;lt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\e&lt;/span&gt;&lt;span class="st"&gt;[1;32mX&lt;/span&gt;&lt;span class="ch"&gt;\e&lt;/span&gt;&lt;span class="st"&gt;[0m&amp;quot;&lt;/span&gt;;&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt;&lt;br /&gt;            std::cout &amp;lt;&amp;lt; c;&lt;br /&gt;    }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whether code or prose, the algorithm is pretty simple. Start at the upper-left corner. As long as we haven't reached the lower-right corner, guess a direction to move. Fail if we go off the edge, run into a wall, or find ourselves on a square we already visited.&lt;/p&gt;&lt;p&gt;Once we've reached the goal, we &lt;a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for-loop"&gt;iterate&lt;/a&gt; over the &lt;code&gt;char&lt;/code&gt; array and print it out with some rad &lt;a href="http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html"&gt;ANSI color codes&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Once again, we're making good use of the fact that our continuations reset global state. That's why we see &lt;code&gt;'X'&lt;/code&gt; marks not on the failed detours, but only on a successful path through the maze. Here's what it looks like.&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code class="sourceCode"&gt;&lt;br /&gt;&lt;span class="kw"&gt;X&lt;/span&gt;-------------+&lt;br /&gt;&lt;span class="kw"&gt;XXXXXXXX&lt;/span&gt;|     |&lt;br /&gt;|--+  |&lt;span class="kw"&gt;X&lt;/span&gt;|   | |&lt;br /&gt;|  |  |&lt;span class="kw"&gt;X&lt;/span&gt;| --+ |&lt;br /&gt;|     |&lt;span class="kw"&gt;XXXXX&lt;/span&gt;| |&lt;br /&gt;|-+---+--+-&lt;span class="kw"&gt;X&lt;/span&gt;| |&lt;br /&gt;| |&lt;span class="kw"&gt;XXX&lt;/span&gt;   | &lt;span class="kw"&gt;XXX&lt;/span&gt;|&lt;br /&gt;| |&lt;span class="kw"&gt;X&lt;/span&gt;|&lt;span class="kw"&gt;X&lt;/span&gt;---+-+-&lt;span class="kw"&gt;X&lt;/span&gt;|&lt;br /&gt;|&lt;span class="kw"&gt;XXX&lt;/span&gt;|&lt;span class="kw"&gt;XXXXXX&lt;/span&gt;|&lt;span class="kw"&gt;XX&lt;/span&gt;|&lt;br /&gt;|&lt;span class="kw"&gt;X&lt;/span&gt;+-+-+--|&lt;span class="kw"&gt;XXX&lt;/span&gt; |&lt;br /&gt;|&lt;span class="kw"&gt;X&lt;/span&gt;|   |  |--- |&lt;br /&gt;|&lt;span class="kw"&gt;XXXX&lt;/span&gt; |       |&lt;br /&gt;|---&lt;span class="kw"&gt;X&lt;/span&gt;-+-------|&lt;br /&gt;|   &lt;span class="kw"&gt;XXXXXXXXXXX&lt;/span&gt;&lt;br /&gt;+-------------&lt;span class="kw"&gt;X&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h1 id="excess-backtracking"&gt;Excess backtracking&lt;/h1&gt;&lt;p&gt;We can run both examples in a single program.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;int&lt;/span&gt; main() {&lt;br /&gt;    factor(&lt;span class="dv"&gt;391&lt;/span&gt;);&lt;br /&gt;    solve_maze();&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we change the maze to be unsolvable, we'll get:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;17 * 23 = 391&lt;br /&gt;23 * 17 = 391&lt;br /&gt;Nothing to be done.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Factoring 391 a different way won't change the maze layout, but the program doesn't know that. We can add a &lt;a href="http://en.wikipedia.org/wiki/Cut_%28logic_programming%29"&gt;cut&lt;/a&gt; primitive to eliminate unwanted backtracking.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="dt"&gt;void&lt;/span&gt; cut() {&lt;br /&gt;    checkpoint = boost::none;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; main() {&lt;br /&gt;    factor(&lt;span class="dv"&gt;391&lt;/span&gt;);&lt;br /&gt;    cut();&lt;br /&gt;    solve_maze();&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 id="the-implementation"&gt;The implementation&lt;/h1&gt;&lt;p&gt;For such a crazy idea, the code to implement &lt;code&gt;call_cc&lt;/code&gt; with &lt;code&gt;fork&lt;/code&gt; is actually pretty reasonable. Here's the core of it.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode cpp"&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &amp;lt;&lt;span class="kw"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span class="co"&gt;// static&lt;/span&gt;&lt;br /&gt;T cont&amp;lt;T&amp;gt;::call_cc(call_cc_arg f) {&lt;br /&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; fd[&lt;span class="dv"&gt;2&lt;/span&gt;];&lt;br /&gt;    pipe(fd);&lt;br /&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; read_fd  = fd[&lt;span class="dv"&gt;0&lt;/span&gt;];&lt;br /&gt;    &lt;span class="dt"&gt;int&lt;/span&gt; write_fd = fd[&lt;span class="dv"&gt;1&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (fork()) {&lt;br /&gt;        &lt;span class="co"&gt;// parent&lt;/span&gt;&lt;br /&gt;        close(read_fd);&lt;br /&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; f( cont&amp;lt;T&amp;gt;(write_fd) );&lt;br /&gt;    } &lt;span class="kw"&gt;else&lt;/span&gt; {&lt;br /&gt;        &lt;span class="co"&gt;// child&lt;/span&gt;&lt;br /&gt;        close(write_fd);&lt;br /&gt;        &lt;span class="dt"&gt;char&lt;/span&gt; buf[&lt;span class="kw"&gt;sizeof&lt;/span&gt;(T)];&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (read(read_fd, buf, &lt;span class="kw"&gt;sizeof&lt;/span&gt;(T)) &amp;lt; ssize_t(&lt;span class="kw"&gt;sizeof&lt;/span&gt;(T)))&lt;br /&gt;            exit(&lt;span class="dv"&gt;0&lt;/span&gt;);&lt;br /&gt;        close(read_fd);&lt;br /&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; *&lt;span class="kw"&gt;reinterpret_cast&lt;/span&gt;&amp;lt;T*&amp;gt;(buf);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;template&lt;/span&gt; &amp;lt;&lt;span class="kw"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; cont&amp;lt;T&amp;gt;::impl::invoke(&lt;span class="dt"&gt;const&lt;/span&gt; T &amp;amp;x) {&lt;br /&gt;    write(m_pipe, &amp;amp;x, &lt;span class="kw"&gt;sizeof&lt;/span&gt;(T));&lt;br /&gt;    exit(&lt;span class="dv"&gt;0&lt;/span&gt;);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To capture a continuation, we fork the process. The resulting processes share a &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/pipe.2.html"&gt;pipe&lt;/a&gt; which was created before the fork. The parent process will call &lt;code&gt;f&lt;/code&gt; immediately, passing a &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; object that holds onto the write end of this pipe. If that continuation is invoked with some argument &lt;code&gt;x&lt;/code&gt;, the parent process will send &lt;code&gt;x&lt;/code&gt; down the pipe and then exit. The child process wakes up from its &lt;code&gt;read&lt;/code&gt; call, and returns &lt;code&gt;x&lt;/code&gt; from &lt;code&gt;call_cc&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;There are a few more implementation details.&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;If the parent process exits, it will close the write end of the pipe, and the child's &lt;code&gt;read&lt;/code&gt; will return 0, i.e. end-of-file. This prevents a buildup of unused continuation processes. But what if the parent deletes the last copy of some &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt;, yet keeps running? We'd like to kill the corresponding child process immediately.&lt;/p&gt;&lt;p&gt;This sounds like a use for a reference-counted smart pointer, but we want to hide this detail from the user. So we split off a private implementation class, &lt;code&gt;cont&amp;lt;T&amp;gt;::impl&lt;/code&gt;, with a destructor that calls &lt;code&gt;close&lt;/code&gt;. The user-facing class &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; holds a &lt;a href="http://en.cppreference.com/w/cpp/memory/shared_ptr"&gt;&lt;code&gt;std::shared_ptr&lt;/code&gt;&lt;/a&gt; to a &lt;code&gt;cont&amp;lt;T&amp;gt;::impl&lt;/code&gt;. And &lt;code&gt;cont&amp;lt;T&amp;gt;::operator()&lt;/code&gt; simply calls &lt;code&gt;cont&amp;lt;T&amp;gt;::impl::invoke&lt;/code&gt; through this pointer.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It would be nice to tell the compiler that &lt;code&gt;cont&amp;lt;T&amp;gt;::operator()&lt;/code&gt; won't return, to avoid warnings like &amp;quot;control reaches end of non-void function&amp;quot;. GCC provides the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bnoreturn_007d-function-attribute-2543"&gt;&lt;code&gt;noreturn&lt;/code&gt; attribute&lt;/a&gt; for this purpose.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We want the &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt; constructor to be private, so we had to make &lt;code&gt;call_cc&lt;/code&gt; a static member function of that class. But the examples above use a free function &lt;code&gt;call_cc&amp;lt;T&amp;gt;&lt;/code&gt;. It's easiest to implement the latter as a 1-line function that calls the former. The alternative is to make it a &lt;a href="http://www.parashift.com/c++-faq-lite/friends.html"&gt;friend&lt;/a&gt; function of &lt;code&gt;cont&amp;lt;T&amp;gt;&lt;/code&gt;, which requires some forward declarations and other noise.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are a number of limitations too.&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;As noted, the forked child process doesn't see changes to the parent's global state. This precludes some interesting uses of continuations, like implementing &lt;a href="http://en.wikipedia.org/wiki/Continuation#Coroutines"&gt;coroutines&lt;/a&gt;. In fact, I had trouble coming up with any application other than backtracking. You could work around this limitation with &lt;a href="http://www.boost.org/doc/libs/1_48_0/doc/html/interprocess/quick_guide.html"&gt;shared memory&lt;/a&gt;, but it seemed like too much hassle.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Each captured continuation can only be invoked once. This is easiest to observe if the code using continuations also invokes &lt;code&gt;fork&lt;/code&gt; directly. It could possibly be fixed with additional &lt;code&gt;fork&lt;/code&gt;ing inside &lt;code&gt;call_cc&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Calling a continuation sends the argument through a pipe using a naive byte-for-byte copy. So the argument needs to be &lt;a href="http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html"&gt;Plain Old Data&lt;/a&gt;, and had better not contain pointers to anything not shared by the two processes. This means we can't send continuations through other continuations, sad to say.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I left out the error handling you would expect in serious code, because this is anything but.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Likewise, I'm assuming that a single &lt;code&gt;write&lt;/code&gt; and &lt;code&gt;read&lt;/code&gt; will suffice to send the value. Robust code will need to loop until completion, handle &lt;code&gt;EINTR&lt;/code&gt;, etc. Or use some higher-level IPC mechanism.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;At some size, stack-allocating the receive buffer will become a problem.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It's slow. Well, actually, I'm impressed with the speed of &lt;code&gt;fork&lt;/code&gt; on Linux. My machine solves both backtracking problems in about a second, &lt;code&gt;fork&lt;/code&gt;ing about 2000 processes along the way. You can speed it up more with &lt;a href="http://9fans.net/archive/2009/02/422"&gt;static linking&lt;/a&gt;. But it's still far more overhead than the alternatives.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As usual, you can get the code from &lt;a href="https://github.com/kmcallister/cccallcc"&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/1563623855220143059-6031546447791889885?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/6031546447791889885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/02/continuations-in-c-with-fork.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6031546447791889885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6031546447791889885'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/02/continuations-in-c-with-fork.html' title='Continuations in C++ with fork'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-3013561900404693703</id><published>2012-02-02T13:24:00.000-08:00</published><updated>2012-02-02T13:35:21.740-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='computability'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Generating random functions</title><content type='html'>&lt;p&gt;How can we pick a random Haskell function? Specifically, we want to write an IO action&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;randomFunction &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with this behavior:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;It produces a function of type &lt;code&gt;Integer -&amp;gt; Bool&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It always produces a total function — a function which never throws an exception or enters an infinite loop.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is equally likely to produce &lt;em&gt;any&lt;/em&gt; such function.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is tricky, because there are infinitely many such functions (more on that later).&lt;/p&gt;&lt;p&gt;In another language we might produce something which looks like a function, but actually flips a coin on each new integer input. It would use mutable state to remember previous results, so that future calls will be consistent. But the Haskell type we gave for &lt;code&gt;randomFunction&lt;/code&gt; forbids this approach. &lt;code&gt;randomFunction&lt;/code&gt; uses IO effects to pick a random function, but the function it picks has access to neither coin flips nor mutable state.&lt;/p&gt;&lt;p&gt;Alternatively, we could build a lazy infinite data structure containing all the &lt;code&gt;Bool&lt;/code&gt; answers we need. &lt;code&gt;randomFunction&lt;/code&gt; could generate an &lt;a href="http://lambda.haskell.org/platform/doc/current/ghc-doc/libraries/random-1.0.0.3/System-Random.html#v:randomRs"&gt;infinite list of random &lt;code&gt;Bool&lt;/code&gt;s&lt;/a&gt;, and produce a function &lt;code&gt;f&lt;/code&gt; which indexes into that list. But this indexing will be inefficient in space and time. If the user calls &lt;code&gt;(f 10000000)&lt;/code&gt;, we'll have to run 10,000,000 steps of the pseudo-random number generator, and build 10,000,000 list elements, before we can return a single &lt;code&gt;Bool&lt;/code&gt; result.&lt;/p&gt;&lt;p&gt;We can improve this considerably by using a different infinite data structure. Though our solution is pure functional code, we &lt;em&gt;do&lt;/em&gt; end up relying on mutation — the implicit mutation by which lazy thunks become evaluated data.&lt;/p&gt;&lt;h1 id="the-data-structure"&gt;The data structure&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.Random&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.List&lt;/span&gt; ( genericIndex )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our data structure is an infinite binary tree:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Tree&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Node&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt; &lt;span class="dt"&gt;Tree&lt;/span&gt; &lt;span class="dt"&gt;Tree&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can interpret such a tree as a function from non-negative &lt;code&gt;Integer&lt;/code&gt;s to &lt;code&gt;Bool&lt;/code&gt;s. If the &lt;code&gt;Integer&lt;/code&gt; argument is zero, the root node holds our &lt;code&gt;Bool&lt;/code&gt; answer. Otherwise, we shift off the least-significant bit of the argument, and look at the left or right subtree depending on that bit.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;get &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Tree&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;)&lt;br /&gt;get (&lt;span class="dt"&gt;Node&lt;/span&gt; b _ _) &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; b&lt;br /&gt;get (&lt;span class="dt"&gt;Node&lt;/span&gt; _ x y) n &lt;span class="fu"&gt;=&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="fu"&gt;divMod&lt;/span&gt; n &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="kw"&gt;of&lt;/span&gt;&lt;br /&gt;        (m, &lt;span class="dv"&gt;0&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; get x m&lt;br /&gt;        (m, _) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; get y m&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we need to build a suitable tree, starting from a &lt;a href="http://lambda.haskell.org/platform/doc/current/ghc-doc/libraries/random-1.0.0.3/System-Random.html#t:StdGen"&gt;random number generator state&lt;/a&gt;. The standard &lt;code&gt;System.Random&lt;/code&gt; module is not going to win any &lt;a href="http://www.serpentine.com/blog/2009/09/19/a-new-pseudo-random-number-generator-for-haskell/"&gt;speed contests&lt;/a&gt;, but it does have one extremely nice property: it supports an operation&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;split &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;StdGen&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;StdGen&lt;/span&gt;, &lt;span class="dt"&gt;StdGen&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The two generator states returned by &lt;code&gt;split&lt;/code&gt; will (ideally) produce two independent streams of random values. We use &lt;code&gt;split&lt;/code&gt; at each node of the infinite tree.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;build &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;StdGen&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Tree&lt;/span&gt;&lt;br /&gt;build g0 &lt;span class="fu"&gt;=&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; (b,  g1) &lt;span class="fu"&gt;=&lt;/span&gt; random g0&lt;br /&gt;        (g2, g3) &lt;span class="fu"&gt;=&lt;/span&gt; split  g1&lt;br /&gt;    &lt;span class="kw"&gt;in&lt;/span&gt;  &lt;span class="dt"&gt;Node&lt;/span&gt; b (build g2) (build g3)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a recursive function with no base case. Conceptually, it produces an infinite tree. Operationally, it produces a single &lt;code&gt;Node&lt;/code&gt; constructor, whose fields are lazily-deferred computations. As &lt;code&gt;get&lt;/code&gt; explores this notional infinite tree, new &lt;code&gt;Node&lt;/code&gt;s are created and randomness generated on demand.&lt;/p&gt;&lt;p&gt;&lt;code&gt;get&lt;/code&gt; traverses one level per bit of its input integer. So looking up the integer &lt;em&gt;n&lt;/em&gt; involves traversing and possibly creating &lt;span style="white-space:nowrap;"&gt;&lt;em&gt;O&lt;/em&gt;(log &lt;em&gt;n&lt;/em&gt;)&lt;/span&gt; nodes. This suggests good space and time efficiency, though only testing will say for sure.&lt;/p&gt;&lt;p&gt;Now we have all the pieces to solve the original puzzle. We build two trees, one to handle positive numbers and another for negative numbers.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;randomFunction &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;)&lt;br /&gt;randomFunction &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    neg &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; build &lt;span class="ot"&gt;`fmap`&lt;/span&gt; newStdGen&lt;br /&gt;    pos &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; build &lt;span class="ot"&gt;`fmap`&lt;/span&gt; newStdGen&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; f n &lt;span class="fu"&gt;|&lt;/span&gt; n &lt;span class="fu"&gt;&amp;lt;&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;     &lt;span class="fu"&gt;=&lt;/span&gt; get neg (&lt;span class="fu"&gt;-&lt;/span&gt;n)&lt;br /&gt;            &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; get pos n&lt;br /&gt;    &lt;span class="fu"&gt;return&lt;/span&gt; f&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 id="testing"&gt;Testing&lt;/h1&gt;&lt;p&gt;Here's some code which helps us visualize one of these functions in the vicinity of zero:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;test &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; (&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;test f &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; (char &lt;span class="fu"&gt;.&lt;/span&gt; f) [&lt;span class="fu"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;40&lt;/span&gt;&lt;span class="fu"&gt;..&lt;/span&gt;&lt;span class="dv"&gt;40&lt;/span&gt;] &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    char &lt;span class="dt"&gt;False&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="ch"&gt;' '&lt;/span&gt;&lt;br /&gt;    char &lt;span class="dt"&gt;True&lt;/span&gt;  &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="ch"&gt;'-'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can test &lt;code&gt;randomFunction&lt;/code&gt; in GHCi:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;randomFunction &amp;gt;&amp;gt;= test&lt;/span&gt;&lt;br /&gt;---- -   ---   -    - -   - --   - - -  -- --- -- --          - -- - - --  --- --&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;randomFunction &amp;gt;&amp;gt;= test&lt;/span&gt;&lt;br /&gt;-   ---- - - - -  - - -- -   -     ---  --- -- - --  -  --    - -  - - -  --   - &lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;randomFunction &amp;gt;&amp;gt;= test&lt;/span&gt;&lt;br /&gt;- ---  - - -  --  ---         -  --  -  -    -  -  - ---- - -  ---   -     -    -&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each result from &lt;code&gt;randomFunction&lt;/code&gt; is indeed a function: it always gives the same output for a given input. This much should be clear from the fact that we haven't used any &lt;a href="http://lambda.haskell.org/platform/doc/current/ghc-doc/libraries/base-4.3.1.0/System-IO-Unsafe.html"&gt;unsafe shenanigans&lt;/a&gt;. But we can also demonstrate it empirically:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;f &amp;lt;- randomFunction&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;test f&lt;/span&gt;&lt;br /&gt;-   -----  - -   -- - -   --- --  - -   - -   - -   -- - -   ---- - - - -  - --- &lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;test f&lt;/span&gt;&lt;br /&gt;-   -----  - -   -- - -   --- --  - -   - -   - -   -- - -   ---- - - - -  - --- &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's also test the speed on some very large arguments:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;:set +s&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;f 10000000&lt;/span&gt;&lt;br /&gt;True&lt;br /&gt;(0.03 secs, 12648232 bytes)&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;f (2^65536)&lt;/span&gt;&lt;br /&gt;True&lt;br /&gt;(1.10 secs, 569231584 bytes)&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;f (2^65536)&lt;/span&gt;&lt;br /&gt;True&lt;br /&gt;(0.26 secs, 426068040 bytes)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second call with &lt;code&gt;2^65536&lt;/code&gt; is faster because the tree nodes already exist in memory. We can expect our tests to be faster yet if we compile with &lt;code&gt;ghc -O&lt;/code&gt; rather than using GHCi's bytecode interpreter.&lt;/p&gt;&lt;h1 id="how-many-functions"&gt;How many functions?&lt;/h1&gt;&lt;p&gt;Assume we have infinite memory, so that &lt;code&gt;Integer&lt;/code&gt;s really can be unboundedly large. And let's ignore negative numbers, for simplicity. How many total functions of type &lt;code&gt;Integer -&amp;gt; Bool&lt;/code&gt; are there?&lt;/p&gt;&lt;p&gt;Suppose we made an infinite list &lt;code&gt;xs&lt;/code&gt; of all such functions. Now consider this definition:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;diag &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; [&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Bool&lt;/span&gt;)&lt;br /&gt;diag xs n &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;not&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt; genericIndex xs n n&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For an argument &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;diag xs&lt;/code&gt; looks at what the &lt;code&gt;n&lt;/code&gt;th function of &lt;code&gt;xs&lt;/code&gt; would return, and returns the opposite. This means the function &lt;code&gt;diag xs&lt;/code&gt; differs from every function in our supposedly comprehensive list of functions. This contradiction shows that there are &lt;a href="http://en.wikipedia.org/wiki/Uncountable_set"&gt;uncountably many&lt;/a&gt; total functions of type &lt;code&gt;Integer -&amp;gt; Bool&lt;/code&gt;. It's closely related to &lt;a href="http://en.wikipedia.org/wiki/Cantor%27s_diagonal_argument"&gt;Cantor's diagonal argument&lt;/a&gt; that the real numbers are uncountable.&lt;/p&gt;&lt;p&gt;But wait, there are only countably many Haskell programs! In fact, you can encode each one as a number. There may be uncountably many functions, but there are only a countable number of &lt;em&gt;computable&lt;/em&gt; functions. So the proof breaks down if you restrict it to a real programming language like Haskell.&lt;/p&gt;&lt;p&gt;In that context, the existence of &lt;code&gt;xs&lt;/code&gt; implies that there is some &lt;em&gt;algorithm&lt;/em&gt; to enumerate the computable total functions. This is the assumption we ultimately contradict. The set of computable total functions is not &lt;a href="http://en.wikipedia.org/wiki/Recursively_enumerable_language"&gt;recursively enumerable&lt;/a&gt;, even though it is countable. Intuitively, to produce a single element of this set, we would have to verify that the function halts on every input, which is &lt;a href="http://en.wikipedia.org/wiki/Halting_problem"&gt;impossible in the general case&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now let's revisit &lt;code&gt;randomFunction&lt;/code&gt;. Any function it produces is computable: the algorithm is a combination of the pseudo-random number procedure and our tree traversal. In this sense, &lt;code&gt;randomFunction&lt;/code&gt; provides extremely poor randomness; it only selects values from a particular &lt;a href="http://en.wikipedia.org/wiki/Null_set"&gt;measure zero&lt;/a&gt; subset of its result type! But if you read the type constructor &lt;code&gt;(-&amp;gt;)&lt;/code&gt; as &amp;quot;computable function&amp;quot;, as one should in a programming language, then &lt;code&gt;randomFunction&lt;/code&gt; is closer to doing what it says it does.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; See also Luke Palmer's &lt;a href="http://lukepalmer.wordpress.com/2012/01/26/computably-uncountable/"&gt;recent article on this subject&lt;/a&gt;.&lt;/p&gt;&lt;h1 id="see-also"&gt;See also&lt;/h1&gt;&lt;p&gt;The libraries &lt;a href="http://hackage.haskell.org/package/data-memocombinators"&gt;data-memocombinators&lt;/a&gt; and &lt;a href="http://hackage.haskell.org/package/MemoTrie"&gt;MemoTrie&lt;/a&gt; use similar structures, not for building random functions but for &lt;a href="http://en.wikipedia.org/wiki/Memoization"&gt;memoizing&lt;/a&gt; existing ones.&lt;/p&gt;&lt;p&gt;You can download this post as a &lt;a href="https://github.com/kmcallister/blog-misc/blob/master/random-function/random-function.lhs"&gt;Literate Haskell file&lt;/a&gt; and play with the code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-3013561900404693703?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/3013561900404693703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/02/generating-random-functions.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3013561900404693703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3013561900404693703'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/02/generating-random-functions.html' title='Generating random functions'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-8551602144136131794</id><published>2012-01-28T09:02:00.000-08:00</published><updated>2012-01-28T09:02:23.660-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='slides'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Writing kernel exploits</title><content type='html'>&lt;p&gt;Yesterday I gave a talk about writing kernel exploits. I've posted the &lt;a href="http://ugcs.net/~keegan/talks/kernel-exploit/talk.pdf"&gt;slides [PDF]&lt;/a&gt;. Here is the original description:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Did you know that a NULL pointer can compromise your entire system? Do you know how UNIX pipes, multithreading, and an obscure network protocol from 1981 are combined to take over Linux machines today? OS kernels are full of strange and interesting vulnerabilities, thanks to the subtle nature of systems code. And the kernel's ultimate authority is the ultimate prize for an attacker.&lt;/p&gt;&lt;p&gt;In this talk you will learn how kernel exploits work, with detailed code examples. Compared to userspace, exploiting the kernel requires a whole different bag of tricks, and we'll cover some of the most important ones. We will focus on Linux systems and x86 hardware, though most ideas will generalize. We'll start with a few toy examples, then look at some real, high-profile Linux exploits from the past two years.&lt;/p&gt;&lt;p&gt;You will also see how to protect your own Linux machines against kernel exploits. We'll talk about the continual cat-and-mouse game between system administrators and those who would attack even hardened kernels.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Thanks again to &lt;a href="http://sipb.mit.edu/"&gt;SIPB&lt;/a&gt; for giving me a venue to talk about whatever I find interesting.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-8551602144136131794?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/8551602144136131794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/writing-kernel-exploits.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8551602144136131794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8551602144136131794'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/writing-kernel-exploits.html' title='Writing kernel exploits'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-3687144062173092177</id><published>2012-01-19T09:51:00.000-08:00</published><updated>2012-01-19T09:51:52.208-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Embedding GDB breakpoints in C source code</title><content type='html'>&lt;p&gt;Have you ever wanted to embed &lt;a href="http://www.gnu.org/software/gdb/"&gt;GDB&lt;/a&gt; breakpoints in C source code?&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;int&lt;/span&gt; main() {&lt;br /&gt;    printf(&lt;span class="st"&gt;&amp;quot;Hello,&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;    EMBED_BREAKPOINT;&lt;br /&gt;    printf(&lt;span class="st"&gt;&amp;quot;world!&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;    EMBED_BREAKPOINT;&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One way is to directly insert your CPU's breakpoint instruction. On x86:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="ot"&gt;#define EMBED_BREAKPOINT&lt;/span&gt;  &lt;span class="kw"&gt;asm&lt;/span&gt; &lt;span class="kw"&gt;volatile&lt;/span&gt; (&lt;span class="st"&gt;&amp;quot;int3;&amp;quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are at least two problems with this approach:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;They aren't real GDB breakpoints. You can't &lt;code&gt;disable&lt;/code&gt; them, count how many times they've been hit, etc.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you run the program outside GDB, the breakpoint instruction will crash your process.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here is a small hack which solves both problems:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="ot"&gt;#define EMBED_BREAKPOINT&lt;/span&gt; \&lt;br /&gt;    &lt;span class="kw"&gt;asm&lt;/span&gt;(&lt;span class="st"&gt;&amp;quot;0:&amp;quot;&lt;/span&gt;                              \&lt;br /&gt;        &lt;span class="st"&gt;&amp;quot;.pushsection embed-breakpoints;&amp;quot;&lt;/span&gt; \&lt;br /&gt;        &lt;span class="st"&gt;&amp;quot;.quad 0b;&amp;quot;&lt;/span&gt;                       \&lt;br /&gt;        &lt;span class="st"&gt;&amp;quot;.popsection;&amp;quot;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We place a &lt;a href="http://sourceware.org/binutils/docs-2.21/as/Symbol-Names.html#index-local-labels-217"&gt;local label&lt;/a&gt; into the instruction stream, and then save its address in the &lt;code&gt;embed-breakpoints&lt;/code&gt; linker section.&lt;/p&gt;&lt;p&gt;Then we need to convert these addresses into GDB &lt;code&gt;breakpoint&lt;/code&gt; commands. I wrote a tool that does this, as a wrapper for the &lt;code&gt;gdb&lt;/code&gt; command. Here's how it works, on our initial example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;gcc -g -o example example.c&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;./gdb-with-breakpoints ./example&lt;/span&gt;&lt;br /&gt;Reading symbols from example...done.&lt;br /&gt;Breakpoint 1 at 0x4004f2: file example.c, line 8.&lt;br /&gt;Breakpoint 2 at 0x4004fc: file example.c, line 10.&lt;br /&gt;&lt;span class="Prompt"&gt;(gdb)&lt;/span&gt; &lt;span class="Entry"&gt;run&lt;/span&gt;&lt;br /&gt;Starting program: example &lt;br /&gt;Hello,&lt;br /&gt;&lt;br /&gt;Breakpoint 1, main () at example.c:8&lt;br /&gt;8           printf(&amp;quot;world!\n&amp;quot;);&lt;br /&gt;&lt;span class="Prompt"&gt;(gdb)&lt;/span&gt; &lt;span class="Entry"&gt;info breakpoints&lt;/span&gt;&lt;br /&gt;Num     Type           Disp Enb Address            What&lt;br /&gt;1       breakpoint     keep y   0x00000000004004f2 in main at example.c:8&lt;br /&gt;        breakpoint already hit 1 time&lt;br /&gt;2       breakpoint     keep y   0x00000000004004fc in main at example.c:10&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we run the program normally, or in GDB without the wrapper, the &lt;code&gt;EMBED_BREAKPOINT&lt;/code&gt; statements do nothing. The breakpoint addresses aren't even loaded into memory, because the &lt;code&gt;embed-breakpoints&lt;/code&gt; section is not marked as &lt;a href="http://sourceware.org/binutils/docs/as/Section.html#index-Section-Stack-443"&gt;allocatable&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can find all of the code &lt;a href="https://github.com/kmcallister/embedded-breakpoints"&gt;on GitHub&lt;/a&gt; under a BSD license. I've done only minimal testing, but I hope it will be a useful debugging tool for someone. Let me know if you find any bugs or improvements. You can comment here, or find my email address on GitHub.&lt;/p&gt;&lt;p&gt;I'm not sure about the decision to write the GDB wrapper in C using &lt;a href="http://sourceware.org/binutils/docs/bfd/"&gt;BFD&lt;/a&gt;. I also considered Haskell and &lt;a href="http://hackage.haskell.org/package/elf"&gt;&lt;code&gt;elf&lt;/code&gt;&lt;/a&gt;, or Python and the new &lt;a href="http://eli.thegreenplace.net/2012/01/06/pyelftools-python-library-for-parsing-elf-and-dwarf/"&gt;pyelftools&lt;/a&gt;. One can probably do something nicer using the GDB &lt;a href="http://sourceware.org/gdb/onlinedocs/gdb/Python.html"&gt;Python API&lt;/a&gt;, which was added &lt;a href="http://lwn.net/Articles/356044/"&gt;a few years ago&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This code depends on a GNU toolchain: it uses GNU C extensions, GNU assembler syntax, and BFD. The GDB wrapper uses the Linux &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html"&gt;&lt;code&gt;proc&lt;/code&gt; filesystem&lt;/a&gt;, so that it can pass to GDB a temporary file which has already been &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/unlink.2.html"&gt;unlinked&lt;/a&gt;. You could port it to other UNIX systems by changing the tempfile handling. It should work on a variety of CPU architectures, but I've only tested it on 32- and 64-bit x86.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-3687144062173092177?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/3687144062173092177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/embedding-gdb-breakpoints-in-c-source.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3687144062173092177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3687144062173092177'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/embedding-gdb-breakpoints-in-c-source.html' title='Embedding GDB breakpoints in C source code'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4245608045489331087</id><published>2012-01-09T22:41:00.000-08:00</published><updated>2012-01-10T01:04:00.829-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mit'/><category scheme='http://www.blogger.com/atom/ns#' term='6.S184'/><category scheme='http://www.blogger.com/atom/ns#' term='compsci'/><title type='text'>Zombie 6.001 starts tomorrow!</title><content type='html'>&lt;p&gt;The &lt;a href="http://web.mit.edu/alexmv/6.S184/"&gt;student-run revival&lt;/a&gt; of MIT's &lt;a href="http://sicp.csail.mit.edu/Spring-2007/"&gt;famous intro CS class&lt;/a&gt; starts tomorrow! 6.001 and its text &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;&lt;em&gt;SICP&lt;/em&gt;&lt;/a&gt; had a singular influence on the teaching of introductions to computer science — not to be confused with intro to programming, worthwhile though that subject may be. After the unfortunate demise of 6.001 at MIT, some former TAs reanimated the class as an intense four-week experience. As &lt;a href="http://web.mit.edu/alexmv/6.S184/"&gt;their description&lt;/a&gt; says:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Zombie-like, 6.001 rises from the dead to threaten students again. Unlike a zombie, though, it's moving quite a bit faster than it did the first time. Like the original, don't walk into the class expecting that it will teach you Scheme; instead, it attempts to teach thought patterns for computer science, and the structure and interpretation of computer programs. Three projects will be assigned and graded. Prereq: some programming experience; high confusion threshold.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I'm helping teach it this year, and it should be a lot of fun. You can &lt;a href="http://web.mit.edu/alexmv/6.S184/"&gt;follow along online&lt;/a&gt; or if you're in the area, come to lectures Tuesdays and Thursdays, 19:00 to 21:00 in 32-044 (that's MIT building 32, room 044).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4245608045489331087?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4245608045489331087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/zombie-6001-starts-tomorrow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4245608045489331087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4245608045489331087'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2012/01/zombie-6001-starts-tomorrow.html' title='Zombie 6.001 starts tomorrow!'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-8375049702846544984</id><published>2011-12-21T16:59:00.000-08:00</published><updated>2011-12-21T16:59:42.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='propane'/><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Propane: Functional synthesis of images and animations in Haskell</title><content type='html'>&lt;p&gt;I just released &lt;a href="http://hackage.haskell.org/package/propane"&gt;Propane&lt;/a&gt;, a Haskell libary for functional synthesis of images and animations. This is a generalization of my &lt;a href="http://repa.ouroborus.net/"&gt;Repa&lt;/a&gt;-based &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/10/quasicrystals-as-sums-of-waves-in-plane.html"&gt;quasicrystal code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It's based on the same ideas as &lt;a href="http://conal.net/Pan/"&gt;Pan&lt;/a&gt; and some other projects. An image is a function assigning a color to each point in the plane. Similarly, an animation assigns an image to each point in time. Haskell's tools for functional and declarative programming can be used directly on images and animations.&lt;/p&gt;&lt;p&gt;For example, you can draw a red-green gradient like so:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Propane&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; saveImage &lt;span class="st"&gt;&amp;quot;out.png&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Size&lt;/span&gt; &lt;span class="dv"&gt;400&lt;/span&gt; &lt;span class="dv"&gt;400&lt;/span&gt;) im &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    im (x,y) &lt;span class="fu"&gt;=&lt;/span&gt; cRGB (unbal x) (unbal y) &lt;span class="dv"&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here &lt;code&gt;im&lt;/code&gt; is the image as a function, mapping an (&lt;em&gt;x&lt;/em&gt;,&lt;em&gt;y&lt;/em&gt;) coordinate to a color. &lt;code&gt;unbal&lt;/code&gt; is a function provided by Propane, which just maps the interval [-1, 1] to [0, 1].&lt;/p&gt;&lt;p&gt;The source package includes an animated quasicrystal and several other &lt;a href="https://github.com/kmcallister/propane/tree/master/examples"&gt;examples&lt;/a&gt;. Propane uses &lt;a href="http://repa.ouroborus.net/"&gt;Repa&lt;/a&gt; for data-parallel array computations. That means it automatically uses multiple CPU cores for rendering, provided the program is compiled and run with threads enabled. That said, it's not yet been optimized for speed in other ways.&lt;/p&gt;&lt;p&gt;This is just a toy right now, but do let me know if you come up with cool enhancements or examples!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-8375049702846544984?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/8375049702846544984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/12/propane-functional-synthesis-of-images.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8375049702846544984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8375049702846544984'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/12/propane-functional-synthesis-of-images.html' title='Propane: Functional synthesis of images and animations in Haskell'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-6481800066023872533</id><published>2011-11-07T05:39:00.000-08:00</published><updated>2011-11-07T05:53:21.824-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tracepoints'/><category scheme='http://www.blogger.com/atom/ns#' term='donttrythisathome'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Self-modifying code for debug tracing in quasi-C</title><content type='html'>&lt;p&gt;Printing a program's state as it runs is the simple but effective debugging tool of programmers everywhere. For efficiency, we usually disable the most verbose output in production. But sometimes you need to diagnose a problem in a deployed system. It would be convenient to declare &amp;quot;tracepoints&amp;quot; and enable them at runtime, like so:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;tracepoint foo_entry;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; foo(&lt;span class="dt"&gt;int&lt;/span&gt; n) {&lt;br /&gt;  TRACE(foo_entry, &lt;span class="st"&gt;&amp;quot;called foo(%d)&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;, n);&lt;br /&gt;  &lt;span class="co"&gt;// ...&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;// Called from UI, monitoring interface, etc.&lt;/span&gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; debug_foo() {&lt;br /&gt;  enable(&amp;amp;foo_entry);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here's a simple implementation of this API:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="kw"&gt;typedef&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; tracepoint;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;#define TRACE(_point, _args...) \&lt;br /&gt;  do {                          \&lt;br /&gt;    if (_point) printf(_args);  \&lt;br /&gt;  } while (0)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;static&lt;/span&gt; &lt;span class="kw"&gt;inline&lt;/span&gt; &lt;span class="dt"&gt;void&lt;/span&gt; enable(tracepoint *point) {&lt;br /&gt;  *point = &lt;span class="dv"&gt;1&lt;/span&gt;;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each tracepoint is simply a global variable. The construct &lt;code&gt;do { ...  } while (0)&lt;/code&gt; is a standard trick to make macro-expanded code play nicely with its surroundings. We also use GCC's syntax for &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros"&gt;macros with a variable number of arguments&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This approach does introduce a bit of overhead. One concern is that reading a global variable will cause a cache miss and will also evict a line of useful data from the cache. There's also some impact from adding a branch instruction. We'll develop a significantly more complicated implementation which avoids both of these problems.&lt;/p&gt;&lt;p&gt;Our new solution will be specific to &lt;a href="http://en.wikipedia.org/wiki/X86-64"&gt;x86-64&lt;/a&gt; processors running Linux, though the idea can be ported to other platforms. This approach is inspired by various self-modifying-code schemes in the Linux kernel, such as &lt;a href="http://lwn.net/Articles/343766/"&gt;ftrace&lt;/a&gt;, &lt;a href="http://lwn.net/Articles/132196/"&gt;kprobes&lt;/a&gt;, &lt;a href="http://lwn.net/Articles/245671/"&gt;immediate values&lt;/a&gt;, etc. It's mostly intended as an example of how these tricks work. The code in this article is not production-ready.&lt;/p&gt;&lt;h1 id="the-design"&gt;The design&lt;/h1&gt;&lt;p&gt;Our new &lt;code&gt;TRACE&lt;/code&gt; macro will produce code like the following pseudo-assembly:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode nasm"&gt;&lt;span class="fu"&gt;foo:&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;span class="co"&gt;; code before tracepoint&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;span class="fu"&gt;tracepoint:&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;nop&lt;/span&gt;&lt;br /&gt;&lt;span class="fu"&gt;after_tracepoint:&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;span class="co"&gt;; rest of function&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;span class="kw"&gt;ret&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fu"&gt;do_tracepoint:&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;push&lt;/span&gt; args to printf&lt;br /&gt;    &lt;span class="kw"&gt;call&lt;/span&gt; printf&lt;br /&gt;    &lt;span class="kw"&gt;jmp&lt;/span&gt; after_tracepoint&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the common case, the tracepoint is disabled, and the overhead is only a single &lt;a href="http://en.wikipedia.org/wiki/NOP"&gt;&lt;code&gt;nop&lt;/code&gt;&lt;/a&gt; instruction. To enable the tracepoint, we replace the &lt;code&gt;nop&lt;/code&gt; instruction in memory with &lt;code&gt;jmp do_tracepoint&lt;/code&gt;.&lt;/p&gt;&lt;h1 id="the-trace-macro"&gt;The &lt;code&gt;TRACE&lt;/code&gt; macro&lt;/h1&gt;&lt;p&gt;Our &lt;code&gt;nop&lt;/code&gt; instruction needs to be big enough that we can overwrite it with an unconditional jump. On x86-64, the standard &lt;code&gt;jmp&lt;/code&gt; instruction has a 1-byte opcode and a 4-byte signed relative displacement, so we need a 5-byte &lt;code&gt;nop&lt;/code&gt;. Five one-byte &lt;code&gt;0x90&lt;/code&gt; instructions would work, but a single five-byte instruction will consume fewer CPU resources. Finding the best way to do nothing is actually rather difficult, but the Linux kernel has already compiled a list of &lt;a href="http://lxr.linux.no/linux+v3.1/arch/x86/include/asm/nops.h"&gt;favorite nops&lt;/a&gt;. We'll use this one:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="ot"&gt;#define NOP5 &lt;/span&gt;&lt;span class="ot"&gt;&amp;quot;.byte 0x0f, 0x1f, 0x44, 0x00, 0x00;&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's check this instruction using &lt;a href="http://udis86.sourceforge.net/"&gt;&lt;code&gt;udcli&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;echo 0f 1f 44 00 00 | udcli -x -64 -att&lt;/span&gt;&lt;br /&gt;0000000000000000 0f1f440000       nop 0x0(%rax,%rax)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;GCC's &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm"&gt;extended inline assembly&lt;/a&gt; lets us insert arbitrarily bizarre assembly code into a normal C program. We'll use the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-asm-with-goto"&gt;&lt;code&gt;asm goto&lt;/code&gt;&lt;/a&gt; flavor, new in GCC 4.5, so that we can pass C labels into our assembly code. (The tracing use case inspired the &lt;code&gt;asm goto&lt;/code&gt; feature, and my macro is adapted from an example in the GCC manual.)&lt;/p&gt;&lt;p&gt;Here's how it looks:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="kw"&gt;typedef&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; tracepoint;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;#define TRACE(_point, _args...)          \&lt;br /&gt;  do {                                   \&lt;br /&gt;    asm goto (                           \&lt;br /&gt;      &amp;quot;0: &amp;quot; NOP5                         \&lt;br /&gt;      &amp;quot;.pushsection trace_table, \&amp;quot;a\&amp;quot;;&amp;quot; \&lt;br /&gt;      &amp;quot;.quad &amp;quot; #_point &amp;quot;, 0b, %l0;&amp;quot;      \&lt;br /&gt;      &amp;quot;.popsection&amp;quot;                      \&lt;br /&gt;      : : : : __lbl_##_point);           \&lt;br /&gt;    if (0) {                             \&lt;br /&gt;      __lbl_##_point: printf(_args);     \&lt;br /&gt;    }                                    \&lt;br /&gt;  } while (0)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We use the &lt;a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html"&gt;stringify&lt;/a&gt; and &lt;a href="http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html"&gt;concat&lt;/a&gt; macro operators, and rely on the gluing together of adjacent string literals. A call like this:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;TRACE(foo_entry, &lt;span class="st"&gt;&amp;quot;called foo(%d)&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;, n);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will produce the following code:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;  &lt;span class="kw"&gt;do&lt;/span&gt; {&lt;br /&gt;    &lt;span class="kw"&gt;asm&lt;/span&gt; &lt;span class="kw"&gt;goto&lt;/span&gt; (&lt;br /&gt;      &lt;span class="st"&gt;&amp;quot;0: .byte 0x0f, 0x1f, 0x44, 0x00, 0x00;&amp;quot;&lt;/span&gt;&lt;br /&gt;      &lt;span class="st"&gt;&amp;quot;.pushsection trace_table, &lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="st"&gt;a&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="st"&gt;;&amp;quot;&lt;/span&gt;&lt;br /&gt;      &lt;span class="st"&gt;&amp;quot;.quad foo_entry, 0b, %l0;&amp;quot;&lt;/span&gt;&lt;br /&gt;      &lt;span class="st"&gt;&amp;quot;.popsection&amp;quot;&lt;/span&gt;&lt;br /&gt;      : : : : __lbl_foo_entry);&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (&lt;span class="dv"&gt;0&lt;/span&gt;) {&lt;br /&gt;      __lbl_foo_entry: printf(&lt;span class="st"&gt;&amp;quot;called foo(%d)&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;, n);&lt;br /&gt;    }&lt;br /&gt;  } &lt;span class="kw"&gt;while&lt;/span&gt; (&lt;span class="dv"&gt;0&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Besides emitting the &lt;code&gt;nop&lt;/code&gt; instruction, we write three 64-bit values (&amp;quot;&lt;code&gt;quad&lt;/code&gt;s&amp;quot;). They are, in order:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;The address of the &lt;code&gt;tracepoint&lt;/code&gt; variable declared by the user. We never actually read or write this variable. We're just using its address as a unique key.&lt;/li&gt;&lt;li&gt;The address of the &lt;code&gt;nop&lt;/code&gt; instruction, by way of a &lt;a href="http://sourceware.org/binutils/docs-2.21/as/Symbol-Names.html#index-local-labels-217"&gt;local assembler label&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The address of the C label for our &lt;code&gt;printf&lt;/code&gt; call, as passed to &lt;code&gt;asm goto&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is the information we need in order to patch in a &lt;code&gt;jmp&lt;/code&gt; at runtime. The &lt;a href="http://sourceware.org/binutils/docs-2.21/as/PushSection.html"&gt;&lt;code&gt;.pushsection&lt;/code&gt;&lt;/a&gt; directive makes the assembler write into the &lt;code&gt;trace_table&lt;/code&gt; &lt;a href="http://sourceware.org/binutils/docs-2.21/as/Secs-Background.html"&gt;section&lt;/a&gt; without disrupting the normal flow of code and data. The &lt;code&gt;&amp;quot;a&amp;quot;&lt;/code&gt; &lt;a href="http://sourceware.org/binutils/docs/as/Section.html#index-Section-Stack-443"&gt;section flag&lt;/a&gt; marks these bytes as &amp;quot;allocatable&amp;quot;, i.e. something we actually want available at runtime.&lt;/p&gt;&lt;p&gt;We count on GCC's optimizer to notice that the condition &lt;code&gt;0&lt;/code&gt; is unlikely to be true, and therefore move the &lt;code&gt;if&lt;/code&gt; body to the end of the function. It's still considered reachable due to the label passed to &lt;code&gt;asm goto&lt;/code&gt;, so it will not fall victim to dead code elimination.&lt;/p&gt;&lt;h1 id="the-linker-script"&gt;The linker script&lt;/h1&gt;&lt;p&gt;We have to collect all of these &lt;code&gt;trace_table&lt;/code&gt; records, possibly from multiple source files, and put them somewhere for use by our C code. We'll do this with the following &lt;a href="http://sourceware.org/binutils/docs/ld/Scripts.html#Scripts"&gt;linker script&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SECTIONS {&lt;br /&gt;  trace_table : {&lt;br /&gt;    trace_table_start = .;&lt;br /&gt;    *(trace_table)&lt;br /&gt;    trace_table_end = .;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This concatenates all &lt;code&gt;trace_table&lt;/code&gt; sections into a single section in the resulting binary. It also provides symbols &lt;code&gt;trace_table_start&lt;/code&gt; and &lt;code&gt;trace_table_end&lt;/code&gt; at the endpoints of this section.&lt;/p&gt;&lt;h1 id="memory-protection"&gt;Memory protection&lt;/h1&gt;&lt;p&gt;Linux systems will prevent an application from overwriting its own code, for &lt;a href="http://www.openbsd.org/papers/ven05-deraadt/mgp00009.html"&gt;good security reasons&lt;/a&gt;, but we can explicitly override these permissions. Memory permissions are managed per &lt;a href="http://en.wikipedia.org/wiki/Page_(computer_memory)"&gt;page&lt;/a&gt; of memory. There's a &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man3/sysconf.3.html"&gt;correct way&lt;/a&gt; to determine the size of a page, but our code is terribly x86-specific anyway, so we'll hardcode the page size of 4096 bytes.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="ot"&gt;#define PAGE_SIZE 4096&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;#define PAGE_OF(_addr) ( ((uint64_t) (_addr)) &amp;amp; ~(PAGE_SIZE-1) )&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we can unprotect an arbitrary region of memory by calling &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/mprotect.2.html"&gt;&lt;code&gt;mprotect&lt;/code&gt;&lt;/a&gt; for the appropriate page(s):&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;static&lt;/span&gt; &lt;span class="dt"&gt;void&lt;/span&gt; unprotect(&lt;span class="dt"&gt;void&lt;/span&gt; *addr, size_t len) {&lt;br /&gt;  &lt;span class="dt"&gt;uint64_t&lt;/span&gt; pg1 = PAGE_OF(addr),&lt;br /&gt;           pg2 = PAGE_OF(addr + len - &lt;span class="dv"&gt;1&lt;/span&gt;);&lt;br /&gt;  &lt;span class="kw"&gt;if&lt;/span&gt; (mprotect((&lt;span class="dt"&gt;void&lt;/span&gt; *) pg1, pg2 - pg1 + PAGE_SIZE,&lt;br /&gt;               PROT_READ | PROT_EXEC | PROT_WRITE)) {&lt;br /&gt;    perror(&lt;span class="st"&gt;&amp;quot;mprotect&amp;quot;&lt;/span&gt;);&lt;br /&gt;    abort();&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We're calling &lt;code&gt;mprotect&lt;/code&gt; on a page which was not obtained from &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html"&gt;&lt;code&gt;mmap&lt;/code&gt;&lt;/a&gt;. POSIX does not define this behavior, but Linux specifically allows &lt;code&gt;mprotect&lt;/code&gt; on any page except the &lt;a href="http://transnum.blogspot.com/2009/01/linuxs-vsyscall.html"&gt;vsyscall page&lt;/a&gt;.&lt;/p&gt;&lt;h1 id="enabling-a-tracepoint"&gt;Enabling a tracepoint&lt;/h1&gt;&lt;p&gt;Now we need to implement the &lt;code&gt;enable&lt;/code&gt; function:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;void&lt;/span&gt; enable(tracepoint *point);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will scan through the &lt;code&gt;trace_table&lt;/code&gt; records looking for a matching &lt;code&gt;tracepoint&lt;/code&gt; pointer. The C struct corresponding to a &lt;code&gt;trace_table&lt;/code&gt; record is:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="kw"&gt;struct&lt;/span&gt; trace_desc {&lt;br /&gt;  tracepoint *point;&lt;br /&gt;  &lt;span class="dt"&gt;void&lt;/span&gt; *jump_from;&lt;br /&gt;  &lt;span class="dt"&gt;void&lt;/span&gt; *jump_to;&lt;br /&gt;} __attribute__((packed));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;packed&lt;/code&gt; attribute tells GCC not to insert any padding within or after these structs. This ensures that their layout will match the records we produced from assembly. Now we can implement a linear search through this table.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;void&lt;/span&gt; enable(tracepoint *point) {&lt;br /&gt;  &lt;span class="kw"&gt;extern&lt;/span&gt; &lt;span class="kw"&gt;struct&lt;/span&gt; trace_desc trace_table_start[], trace_table_end[];&lt;br /&gt;  &lt;span class="kw"&gt;struct&lt;/span&gt; trace_desc *desc;&lt;br /&gt;  &lt;span class="kw"&gt;for&lt;/span&gt; (desc = trace_table_start; desc &amp;lt; trace_table_end; desc++) {&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (desc-&amp;gt;point != point)&lt;br /&gt;      &lt;span class="kw"&gt;continue&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span class="dt"&gt;int64_t&lt;/span&gt; offset = (desc-&amp;gt;jump_to - desc-&amp;gt;jump_from) - &lt;span class="dv"&gt;5&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; ((offset &amp;gt; INT32_MAX) || (offset &amp;lt; INT32_MIN)) {&lt;br /&gt;      fprintf(stderr, &lt;span class="st"&gt;&amp;quot;offset too big: %lx&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;, offset);&lt;br /&gt;      abort();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="dt"&gt;int32_t&lt;/span&gt; offset32 = offset;&lt;br /&gt;    &lt;span class="dt"&gt;unsigned&lt;/span&gt; &lt;span class="dt"&gt;char&lt;/span&gt; *dest = desc-&amp;gt;jump_from;&lt;br /&gt;    unprotect(dest, &lt;span class="dv"&gt;5&lt;/span&gt;);&lt;br /&gt;    dest[&lt;span class="dv"&gt;0&lt;/span&gt;] = &lt;span class="bn"&gt;0xe9&lt;/span&gt;;&lt;br /&gt;    memcpy(dest&lt;span class="dv"&gt;+1&lt;/span&gt;, &amp;amp;offset32, &lt;span class="dv"&gt;4&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We enable a tracepoint by overwriting its &lt;code&gt;nop&lt;/code&gt; with an unconditional jump. The opcode is &lt;code&gt;0xe9&lt;/code&gt;. The operand is a 32-bit displacement, interpreted relative to the instruction &lt;em&gt;after&lt;/em&gt; the jump. &lt;code&gt;desc-&amp;gt;jump_from&lt;/code&gt; points to the beginning of what will be the jump instruction, so we subtract 5 from the displacement. Then we unprotect memory and write the new bytes into place.&lt;/p&gt;&lt;p&gt;That's everything. You can grab all of this code from &lt;a href="https://github.com/kmcallister/tracepoints"&gt;GitHub&lt;/a&gt;, including a simple test program.&lt;/p&gt;&lt;h1 id="pitfalls"&gt;Pitfalls&lt;/h1&gt;&lt;p&gt;Where to start?&lt;/p&gt;&lt;p&gt;This code is extremely non-portable, relying on details of x86-64, Linux, and specific recent versions of the GNU C compiler and assembler. The idea can be ported to other platforms, with some care. For example, ARM processors require an &lt;a href="http://lxr.linux.no/linux+v3.1/arch/arm/include/asm/cacheflush.h#L176"&gt;instruction cache flush&lt;/a&gt; after writing to code. Linux on ARM &lt;a href="http://lxr.linux.no/linux+v3.1/arch/arm/kernel/traps.c#L502"&gt;implements&lt;/a&gt; the &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/cacheflush.2.html"&gt;&lt;code&gt;cacheflush&lt;/code&gt; system call&lt;/a&gt; for this purpose.&lt;/p&gt;&lt;p&gt;Our code is not thread-safe, either. If one thread reaches a &lt;code&gt;nop&lt;/code&gt; while it is being overwritten by another thread, the result will surely be a crash or other horrible bug. The &lt;a href="http://www.ksplice.com/doc/ksplice.pdf"&gt;Ksplice paper&lt;/a&gt; [PDF] discusses how to prevent this, in the context of &lt;a href="http://www.ksplice.com/"&gt;live-patching the Linux kernel&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Is it worth opening this can of worms in order to improve performance a little? In general, no. Obviously we'd have to measure the performance difference to be sure. But for most projects, concerns of maintainability and avoiding bugs will preclude tricky hacks like this one.&lt;/p&gt;&lt;p&gt;The Linux kernel is under extreme demands for both performance and flexibility. It's part of every application on a huge number of systems, so any small performance improvement has a large aggregate effect. And those systems are incredibly diverse, making it likely that &lt;em&gt;someone&lt;/em&gt; will see a large difference. Finally, kernel development will always involve tricky low-level code as a matter of course. The infrastructure is already there to support it — both software infrastructure and knowledgeable developers.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-6481800066023872533?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/6481800066023872533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/self-modifying-code-for-debug-tracing.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6481800066023872533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6481800066023872533'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/self-modifying-code-for-debug-tracing.html' title='Self-modifying code for debug tracing in quasi-C'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-7529328850122408321</id><published>2011-11-04T04:22:00.000-07:00</published><updated>2011-11-04T05:00:18.554-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='global-lock'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Global locking through StablePtr</title><content type='html'>&lt;p&gt;I spoke before of using &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/10/safe-top-level-mutable-variables-for.html"&gt;global locks in Haskell&lt;/a&gt; to protect a thread-unsafe C library. And I wrote about a &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/10/thunks-and-lazy-blackholes-introduction.html"&gt;GHC bug&lt;/a&gt; which breaks the most straightforward way to get a global lock.&lt;/p&gt;&lt;p&gt;My new solution is to store an &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/base-4.3.1.0/Control-Concurrent-MVar.html"&gt;&lt;code&gt;MVar&lt;/code&gt;&lt;/a&gt; lock in a C global variable via &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/Foreign-StablePtr.html"&gt;&lt;code&gt;StablePtr&lt;/code&gt;&lt;/a&gt;. I've implemented this, and it seems to work. I'd appreciate if people could bang on this code and report any issues.&lt;/p&gt;&lt;p&gt;You can get the library from &lt;a href="http://hackage.haskell.org/package/global-lock"&gt;Hackage&lt;/a&gt; or browse &lt;a href="https://github.com/kmcallister/global-lock"&gt;the source&lt;/a&gt;, including a &lt;a href="https://github.com/kmcallister/global-lock/blob/master/test/counter.hs"&gt;test program&lt;/a&gt;. You can also use this code as a template for including a similar lock in your own Haskell project.&lt;/p&gt;&lt;h1 id="the-c-code"&gt;The C code&lt;/h1&gt;&lt;p&gt;On &lt;a href="https://github.com/kmcallister/global-lock/blob/master/cbits/global.c"&gt;the C side&lt;/a&gt;, we declare a global variable and a function to read that variable.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;static&lt;/span&gt; &lt;span class="dt"&gt;void&lt;/span&gt;* global = &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt;* hs_globalzmlock_get_global(&lt;span class="dt"&gt;void&lt;/span&gt;) {&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; global;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To avoid name clashes, I gave this function a long name based on the &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames"&gt;z-encoding&lt;/a&gt; of my package's name. The variable named &lt;code&gt;global&lt;/code&gt; will not conflict with another compilation unit, because it's declared &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Another C function will set this variable, if it was previously 0. Two threads might execute this code concurrently, so we use a GCC &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html"&gt;built-in for atomic memory access&lt;/a&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;&lt;span class="dt"&gt;int&lt;/span&gt; hs_globalzmlock_set_global(&lt;span class="dt"&gt;void&lt;/span&gt;* new_global) {&lt;br /&gt;    &lt;span class="dt"&gt;void&lt;/span&gt;* old = __sync_val_compare_and_swap(&amp;amp;global, &lt;span class="dv"&gt;0&lt;/span&gt;, new_global);&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; (old == &lt;span class="dv"&gt;0&lt;/span&gt;);&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;old&lt;/code&gt; is not 0, then someone has already set &lt;code&gt;global&lt;/code&gt;, and our assignment was dropped. We report this condition to the caller.&lt;/p&gt;&lt;h1 id="foreign-imports"&gt;Foreign imports&lt;/h1&gt;&lt;p&gt;On &lt;a href="https://github.com/kmcallister/global-lock/blob/master/System/GlobalLock/Internal.hs"&gt;the Haskell side&lt;/a&gt;, we import these C functions.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;foreign import ccall unsafe&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;hs_globalzmlock_get_global&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;    c_get_global &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;Ptr&lt;/span&gt; ())&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;foreign import ccall&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;hs_globalzmlock_set_global&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;    c_set_global &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Ptr&lt;/span&gt; () &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;CInt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;unsafe&lt;/code&gt; import of &lt;code&gt;c_get_global&lt;/code&gt; demands justification. This wrinkle arises from the fact that GHC runs many Haskell threads on the same OS thread. A long-running foreign call from that OS thread might &lt;a href="http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/"&gt;block unrelated Haskell code&lt;/a&gt;. GHC prevents this by moving the foreign call and/or other Haskell threads to a different OS thread. This adds latency to the foreign call — about 100 nanoseconds in my tests.&lt;/p&gt;&lt;p&gt;In most cases a 100 ns overhead is negligible. But it matters for functions which are guaranteed to return in a very short amount of time. And blocking other Haskell threads during such a short call is fine. Marking the import &lt;code&gt;unsafe&lt;/code&gt; tells GHC to ignore the blocking concern, and generate a direct C function call.&lt;/p&gt;&lt;p&gt;Our function &lt;code&gt;c_get_global&lt;/code&gt; is a good use case for &lt;code&gt;unsafe&lt;/code&gt;, because it simply returns a global variable. In my &lt;a href="https://github.com/kmcallister/global-lock/blob/master/test/bench.hs"&gt;tests&lt;/a&gt;, adding &lt;code&gt;unsafe&lt;/code&gt; decreased the overall latency of locking by about 50%. We cannot use &lt;code&gt;unsafe&lt;/code&gt; with &lt;code&gt;c_set_global&lt;/code&gt; because, in the worst case, GCC implements atomic operations with blocking library functions. That's okay because &lt;code&gt;c_set_global&lt;/code&gt; will only be called a few times anyway.&lt;/p&gt;&lt;h1 id="the-haskell-code"&gt;The Haskell code&lt;/h1&gt;&lt;p&gt;Now we have access to a C global of type &lt;code&gt;void*&lt;/code&gt;, and we want to store a Haskell value of type &lt;code&gt;MVar ()&lt;/code&gt;. The &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/Foreign-StablePtr.html"&gt;&lt;code&gt;StablePtr&lt;/code&gt;&lt;/a&gt; module is just what we need. A &lt;code&gt;StablePtr&lt;/code&gt; is a reference to some Haskell expression, which can be converted to &lt;code&gt;Ptr ()&lt;/code&gt;, aka &lt;code&gt;void*&lt;/code&gt;. There is no guarantee about this &lt;code&gt;Ptr ()&lt;/code&gt; value, except that it can be converted back to the original &lt;code&gt;StablePtr&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Here's how we store an &lt;code&gt;MVar&lt;/code&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;set &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;set &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    mv  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; newMVar ()&lt;br /&gt;    ptr &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; newStablePtr mv&lt;br /&gt;    ret &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; c_set_global (castStablePtrToPtr ptr)&lt;br /&gt;    when (ret &lt;span class="fu"&gt;==&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;) &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;        freeStablePtr ptr&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It's fine for two threads to enter &lt;code&gt;set&lt;/code&gt; concurrently. In one thread, the assignment will be dropped, and &lt;code&gt;c_set_global&lt;/code&gt; will return 0. In that case we free the unused &lt;code&gt;StablePtr&lt;/code&gt;, and the &lt;code&gt;MVar&lt;/code&gt; will eventually be garbage-collected. &lt;code&gt;StablePtr&lt;/code&gt;s must be freed manually, because the GHC garbage collector can't tell if some C code has stashed away the corresponding &lt;code&gt;void*&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Now we can retrieve the &lt;code&gt;MVar&lt;/code&gt;, or create it if necessary.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;get &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; (&lt;span class="dt"&gt;MVar&lt;/span&gt; ())&lt;br /&gt;get &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    p &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; c_get_global&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; p &lt;span class="fu"&gt;==&lt;/span&gt; nullPtr&lt;br /&gt;        &lt;span class="kw"&gt;then&lt;/span&gt; set &lt;span class="fu"&gt;&amp;gt;&amp;gt;&lt;/span&gt; get&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt; deRefStablePtr (castPtrToStablePtr p)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the common path, we do an unsynchronized read on the global variable. Only if the variable appears to contain &lt;code&gt;NULL&lt;/code&gt; do we allocate an &lt;code&gt;MVar&lt;/code&gt;, perform a synchronized compare-and-swap, etc. This keeps overhead low, and makes this library suitable for fine-grained locking.&lt;/p&gt;&lt;p&gt;All that's left is the user-visible locking interface:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;lock &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; a&lt;br /&gt;lock act &lt;span class="fu"&gt;=&lt;/span&gt; get &lt;span class="fu"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="fu"&gt;flip&lt;/span&gt; withMVar (&lt;span class="fu"&gt;const&lt;/span&gt; act)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h1 id="inspecting-the-machine-code"&gt;Inspecting the machine code&lt;/h1&gt;&lt;p&gt;Just for fun, let's see how GCC implements &lt;code&gt;__sync_val_compare_and_swap&lt;/code&gt; on the AMD64 architecture.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;objdump -d dist/build/cbits/global.o&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;0000000000000010 &amp;lt;hs_globalzmlock_set_global&amp;gt;:&lt;br /&gt;  10:   31 c0                   xor    %eax,%eax&lt;br /&gt;  12:   f0 48 0f b1 3d 00 00    lock cmpxchg %rdi,0x0(%rip)&lt;br /&gt;  19:   00 00&lt;br /&gt;....&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;code&gt;lock cmpxchg&lt;/code&gt; is the same instruction used by the &lt;a href="http://hackage.haskell.org/trac/ghc/browser/includes/stg/SMP.h?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L165"&gt;GHC runtime system&lt;/a&gt; for its own atomic compare-and-swap. The offset on the operand &lt;code&gt;0x0(%rip)&lt;/code&gt; will be &lt;a href="http://www.iecc.com/linker/linker07.html"&gt;relocated&lt;/a&gt; to point at &lt;code&gt;global&lt;/code&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-7529328850122408321?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/7529328850122408321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/global-locking-through-stableptr.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7529328850122408321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7529328850122408321'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/global-locking-through-stableptr.html' title='Global locking through StablePtr'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-3577785425903756888</id><published>2011-11-03T03:47:00.000-07:00</published><updated>2011-11-03T03:47:09.281-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='boston'/><category scheme='http://www.blogger.com/atom/ns#' term='hackathon'/><title type='text'>Haskell hackathon in the Boston area, January 20 to 22</title><content type='html'>&lt;p&gt;The global sensation that is the &lt;a href="http://haskell.org/haskellwiki/Hackathon"&gt;Haskell Hackathon&lt;/a&gt; is coming to the Boston area. &lt;a href="http://haskell.org/haskellwiki/Hac_Boston"&gt;Hac Boston&lt;/a&gt; will be held &lt;strong&gt;January 20 to 22, 2012&lt;/strong&gt; in &lt;strong&gt;Cambridge, Massachusetts&lt;/strong&gt;. It's open to all; you do not need to be a Haskell guru to attend. All you need is a basic knowledge of Haskell, a willingness to learn, and a &lt;a href="http://haskell.org/haskellwiki/Hac_Boston/Projects"&gt;project&lt;/a&gt; you're excited to help with (or a project of your own to work on).&lt;/p&gt;&lt;p&gt;Spaces are filling up, so be sure to &lt;a href="http://haskell.org/haskellwiki/Hac_Boston/Register"&gt;register&lt;/a&gt; if you plan on coming. You can also coordinate &lt;a href="http://haskell.org/haskellwiki/Hac_Boston/Projects"&gt;projects&lt;/a&gt; on the HaskellWiki.&lt;/p&gt;&lt;p&gt;&lt;a href="http://mit.edu/"&gt;MIT&lt;/a&gt; is providing space (exact room to be determined) and &lt;a href="https://www.capitaliq.com/"&gt;Capital IQ&lt;/a&gt; is sponsoring the event. In addition to coding, there will be food and some short talks. I'm interested in giving a ~20 minute talk of some kind, with slides also available online. What would people like to hear about?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-3577785425903756888?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/3577785425903756888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/haskell-hackathon-in-boston-area.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3577785425903756888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3577785425903756888'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/11/haskell-hackathon-in-boston-area.html' title='Haskell hackathon in the Boston area, January 20 to 22'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-7170898440757064828</id><published>2011-10-31T00:17:00.000-07:00</published><updated>2011-10-31T00:17:50.974-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rts'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='ghc'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Thunks and lazy blackholes: an introduction to GHC at runtime</title><content type='html'>&lt;p&gt;This article is about a &lt;a href="http://haskell.org/ghc/"&gt;GHC&lt;/a&gt; bug I encountered recently, but it's really an excuse to talk about some GHC internals at an intro level. (In turn, an excuse for me to learn about those internals.)&lt;/p&gt;&lt;p&gt;I'll assume you're familiar with the basics of Haskell and lazy evaluation.&lt;/p&gt;&lt;h1 id="the-bug"&gt;The bug&lt;/h1&gt;&lt;p&gt;I spoke &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/10/safe-top-level-mutable-variables-for.html"&gt;before&lt;/a&gt; of using global locks in Haskell to protect a thread-unsafe C library. Unfortunately a &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/5558"&gt;GHC bug&lt;/a&gt; prevents this from working. Using &lt;code&gt;unsafePerformIO&lt;/code&gt; at the top level of a file can result in IO that happens more than once.&lt;/p&gt;&lt;p&gt;Here is a simple program which illustrates the problem:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Concurrent&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Monad&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.IO.Unsafe&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;ioThunk &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; ()&lt;br /&gt;ioThunk &lt;span class="fu"&gt;=&lt;/span&gt; unsafePerformIO &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    me &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; myThreadId&lt;br /&gt;    &lt;span class="fu"&gt;putStrLn&lt;/span&gt; (&lt;span class="st"&gt;&amp;quot;IO executed by &amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;++&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; me)&lt;br /&gt;&lt;span class="ot"&gt;{-# NOINLINE ioThunk #-}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;main &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    replicateM_ &lt;span class="dv"&gt;100&lt;/span&gt; (forkIO (&lt;span class="fu"&gt;print&lt;/span&gt; ioThunk))&lt;br /&gt;    threadDelay &lt;span class="dv"&gt;10000&lt;/span&gt;  &lt;span class="co"&gt;-- wait for other threads&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's test this, following the &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/base-4.3.1.0/System-IO-Unsafe.html#v:unsafePerformIO"&gt;compiler flag recommendations&lt;/a&gt; for &lt;code&gt;unsafePerformIO&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;ghc -V&lt;/span&gt;&lt;br /&gt;The Glorious Glasgow Haskell Compilation System, version 7.2.1&lt;br /&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;ghc -rtsopts -threaded -fno-cse -fno-full-laziness dupe.hs&lt;/span&gt;&lt;br /&gt;[1 of 1] Compiling Main             ( dupe.hs, dupe.o )&lt;br /&gt;Linking dupe ...&lt;br /&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;while true; do ./dupe +RTS -N | head -n 2; echo ----; done&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Within a few seconds I see output like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;----&lt;br /&gt;IO executed by ThreadId 35&lt;br /&gt;()&lt;br /&gt;----&lt;br /&gt;IO executed by ThreadId 78&lt;br /&gt;IO executed by ThreadId 85&lt;br /&gt;----&lt;br /&gt;IO executed by ThreadId 48&lt;br /&gt;()&lt;br /&gt;----&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the middle run, two threads executed the IO action.&lt;/p&gt;&lt;p&gt;This bug was &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/5558"&gt;reported&lt;/a&gt; two weeks ago and is already &lt;a href="http://hackage.haskell.org/trac/ghc/changeset/96c80d34163fd422cbc18f4532b7556212a554b8"&gt;fixed&lt;/a&gt; in GHC HEAD. I tested with GHC 7.3.20111026, aka &lt;code&gt;g6f5b798&lt;/code&gt;, and the problem seemed to go away.&lt;/p&gt;&lt;p&gt;Unfortunately it will be some time before GHC 7.4 is widely deployed, so I'm thinking about workarounds for my original global locking problem. I'll probably store the lock in a C global variable via &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/Foreign-StablePtr.html"&gt;&lt;code&gt;StablePtr&lt;/code&gt;&lt;/a&gt;, or failing that, implement all locking in C. But I'd appreciate any other suggestions.&lt;/p&gt;&lt;p&gt;The remainder of this article is an attempt to explain this GHC bug, and the fix committed by Simon Marlow. It's long because&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;I try not to assume you know anything about how GHC works. I don't know very much, myself.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;There are various digressions.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id="objects-at-runtime"&gt;Objects at runtime&lt;/h1&gt;&lt;p&gt;Code produced by GHC can allocate &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#Typesofobject"&gt;many kinds of objects&lt;/a&gt;. Here are just a few:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#DataConstructors"&gt;&lt;strong&gt;&lt;code&gt;CONSTR&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; objects represent algebraic data constructors and their associated fields. The value &lt;code&gt;(Just 'x')&lt;/code&gt; would be represented by a &lt;code&gt;CONSTR&lt;/code&gt; object, holding a pointer to another object representing &lt;code&gt;'x'&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#FunctionClosures"&gt;&lt;strong&gt;&lt;code&gt;FUN&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; objects represent functions, like the value &lt;code&gt;(\x -&amp;gt;     x+1)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#Thunks"&gt;&lt;strong&gt;&lt;code&gt;THUNK&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; objects represent computations which have not yet happened. Suppose we write:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;let&lt;/span&gt; x &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="fu"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="kw"&gt;in&lt;/span&gt; f x x&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code will construct a &lt;code&gt;THUNK&lt;/code&gt; object for &lt;code&gt;x&lt;/code&gt; and pass it to the code for &lt;code&gt;f&lt;/code&gt;. Some time later, &lt;code&gt;f&lt;/code&gt; may force evaluation of its argument, and the thunk will, in turn, invoke &lt;code&gt;(+)&lt;/code&gt;. When the thunk has finished evaluating, it is overwritten with the evaluation result. (Here, this might be an &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/ghc-prim-0.2.0.0/GHC-Types.html#t:Int"&gt;&lt;code&gt;I#&lt;/code&gt;&lt;/a&gt; &lt;code&gt;CONSTR&lt;/code&gt; holding the number 4.) If &lt;code&gt;f&lt;/code&gt; then forces its second argument, which is &lt;em&gt;also&lt;/em&gt; &lt;code&gt;x&lt;/code&gt;, the work done by &lt;code&gt;(+)&lt;/code&gt; is not repeated. This is the essence of lazy evaluation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When a thunk is forced, it's first overwritten with a &lt;strong&gt;&lt;code&gt;BLACKHOLE&lt;/code&gt;&lt;/strong&gt; object. This &lt;code&gt;BLACKHOLE&lt;/code&gt; is eventually replaced with the evaluation result. Therefore a &lt;code&gt;BLACKHOLE&lt;/code&gt; represents a thunk which is currently being evaluated.&lt;/p&gt;&lt;p&gt;Identifying this case helps the garbage collector, and it also gives GHC its seemingly magical ability to detect some infinite loops. Forcing a &lt;code&gt;BLACKHOLE&lt;/code&gt; indicates a computation which cannot proceed until the same computation has finished. The GHC runtime will terminate the program with a &lt;code&gt;&amp;lt;&amp;lt;loop&amp;gt;&amp;gt;&lt;/code&gt; exception.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We can't truly update thunks in place, because the evaluation result might be larger than the space originally allocated for the thunk. So we write an indirection pointing to the evaluation result. These &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#Indirections"&gt;&lt;strong&gt;&lt;code&gt;IND&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt; objects will later be removed by the garbage collector.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id="static-objects"&gt;Static objects&lt;/h1&gt;&lt;p&gt;Dynamically-allocated objects make sense for values which are created as your program runs. But the top-level declarations in a Haskell module don't need to be dynamically allocated; they already exist when your program starts up. GHC allocates these &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#Staticobjects"&gt;static objects&lt;/a&gt; in your executable's data section, the same place where C global variables live.&lt;/p&gt;&lt;p&gt;Consider this program:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;x &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;Just&lt;/span&gt; &lt;span class="ch"&gt;'x'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;f (&lt;span class="kw"&gt;Just&lt;/span&gt; _) &lt;span class="fu"&gt;=&lt;/span&gt; \y &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; y&lt;span class="fu"&gt;+&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;print&lt;/span&gt; (f x &lt;span class="dv"&gt;3&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ignoring optimizations, GHC will produce code where:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;x&lt;/code&gt; is a &lt;code&gt;CONSTR_STATIC&lt;/code&gt; object.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;f&lt;/code&gt; is a &lt;code&gt;FUN_STATIC&lt;/code&gt; object. When called, &lt;code&gt;f&lt;/code&gt; will return a dynamically-allocated &lt;code&gt;FUN&lt;/code&gt; object representing &lt;code&gt;(\y -&amp;gt; y+1)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;main&lt;/code&gt; is a &lt;code&gt;THUNK_STATIC&lt;/code&gt; object. It represents the unevaluated expression formed by applying the function &lt;code&gt;print&lt;/code&gt; to the argument &lt;code&gt;(f x 3)&lt;/code&gt;. A static thunk is also known as a &lt;a href="http://www.haskell.org/haskellwiki/Constant_applicative_form"&gt;constant applicative form&lt;/a&gt;, or a CAF for short. Like any other thunk, a CAF may or may not get evaluated. If evaluated, it will be replaced with a black hole and eventually the evaluation result. In this example, &lt;code&gt;main&lt;/code&gt; will be evaluated by the runtime system, in deciding what IO to perform.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id="black-holes-and-revelations"&gt;Black holes and revelations&lt;/h1&gt;&lt;p&gt;That's all fine for a single-threaded Haskell runtime, but GHC supports running many Haskell threads across multiple OS threads. This introduces some additional complications. For example, one thread might force a thunk which is currently being evaluated by another thread. The thread will find a &lt;code&gt;BLACKHOLE&lt;/code&gt;, but terminating the program would be incorrect. Instead the &lt;code&gt;BLACKHOLE&lt;/code&gt; puts the current Haskell thread to sleep, and wakes it up when the evaluation result is ready.&lt;/p&gt;&lt;p&gt;If two threads force the same thunk at the same time, they will both perform the deferred computation. We could avoid this wasted effort by writing and checking for black holes using expensive atomic memory operations. But this is a poor tradeoff; we slow down &lt;em&gt;every&lt;/em&gt; evaluation in order to prevent a rare race condition.&lt;/p&gt;&lt;p&gt;As a compiler for a language with pure evaluation, GHC has the luxury of tolerating some duplicated computation. Evaluating an expression twice can't change a program's behavior. And most thunks are cheap to evaluate, hardly worth the effort of avoiding duplication. So GHC follows a &amp;quot;lazy black-holing&amp;quot; strategy.&lt;sup&gt;&lt;a href="#x1fn1" class="footnoteRef" id="x1fnref1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;&lt;a href="#x1fn2" class="footnoteRef" id="x1fnref2"&gt;2&lt;/a&gt;&lt;/sup&gt; Threads write black holes only when they enter the garbage collector. If a thread discovers that one of its thunks has already been claimed, it will abandon the duplicated work-in-progress. This scheme avoids large wasted computations without paying the price on small computations. You can find the gritty details within the function &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/ThreadPaused.c?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L171"&gt;&lt;code&gt;threadPaused&lt;/code&gt;&lt;/a&gt;, in &lt;code&gt;rts/ThreadPaused.c&lt;/code&gt;.&lt;/p&gt;&lt;h1 id="unsafedupableperformio"&gt;&lt;code&gt;unsafe[Dupable]PerformIO&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;You may remember that we started, all those many words ago, with a program that uses &lt;code&gt;unsafePerformIO&lt;/code&gt;. This breaks the pure-evaluation property of Haskell. Repeated evaluation will affect semantics! Might lazy black-holing be the culprit in the original bug?&lt;/p&gt;&lt;p&gt;Naturally, the GHC developers thought about this case. Here's the &lt;a href="http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/src/GHC-IO.html#unsafePerformIO"&gt;implementation of &lt;code&gt;unsafePerformIO&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;unsafePerformIO m &lt;span class="fu"&gt;=&lt;/span&gt; unsafeDupablePerformIO (noDuplicate &lt;span class="fu"&gt;&amp;gt;&amp;gt;&lt;/span&gt; m)&lt;br /&gt;&lt;br /&gt;noDuplicate &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt; \s &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; noDuplicate# s &lt;span class="kw"&gt;of&lt;/span&gt; s' &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (# s', () #)&lt;br /&gt;&lt;br /&gt;unsafeDupablePerformIO (&lt;span class="dt"&gt;IO&lt;/span&gt; m) &lt;span class="fu"&gt;=&lt;/span&gt; lazy (&lt;span class="kw"&gt;case&lt;/span&gt; m realWorld# &lt;span class="kw"&gt;of&lt;/span&gt; (# _, r #) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The core behavior is implemented by &lt;a href="http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/src/GHC-IO.html#unsafeDupablePerformIO"&gt;&lt;code&gt;unsafeDupablePerformIO&lt;/code&gt;&lt;/a&gt;, using GHC's internal representation of IO actions (which is beyond the scope of this article, to the extent I even have a scope in mind). As the name suggests, &lt;code&gt;unsafeDupablePerformIO&lt;/code&gt; provides no guarantee against duplicate execution. The more familiar &lt;code&gt;unsafePerformIO&lt;/code&gt; builds this guarantee by first invoking the &lt;code&gt;noDuplicate#&lt;/code&gt; primitive operation.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/PrimOps.cmm?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L1904"&gt;implementation of &lt;code&gt;noDuplicate#&lt;/code&gt;&lt;/a&gt;, written in GHC's &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/CmmType"&gt;&lt;code&gt;Cmm&lt;/code&gt;&lt;/a&gt; intermediate language, handles a few tricky considerations. But it's basically a call to the function &lt;code&gt;threadPaused&lt;/code&gt;, which we saw is responsible for lazy black-holing. In other words, thunks built from &lt;code&gt;unsafePerformIO&lt;/code&gt; perform eager black-holing.&lt;/p&gt;&lt;p&gt;Since &lt;code&gt;threadPaused&lt;/code&gt; has to walk the evaluation stack, &lt;code&gt;unsafeDupablePerformIO&lt;/code&gt; might be much faster than &lt;code&gt;unsafePerformIO&lt;/code&gt;. In practice, this will matter when performing a great number of very quick IO actions, like &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/Foreign-Storable.html#v:peek"&gt;&lt;code&gt;peek&lt;/code&gt;&lt;/a&gt;ing a single byte from memory. In this case it is safe to duplicate IO, provided the buffer is unchanging. Let's measure the performance difference.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;GHC.IO&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Foreign&lt;/span&gt; &lt;span class="kw"&gt;hiding&lt;/span&gt; (unsafePerformIO)&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.Random&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Criterion.Main&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; sz &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;1024&lt;/span&gt;&lt;span class="fu"&gt;*&lt;/span&gt;&lt;span class="dv"&gt;1024&lt;/span&gt;&lt;br /&gt;    buf &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; mallocBytes sz&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; get    i &lt;span class="fu"&gt;=&lt;/span&gt; peekByteOff buf&lt;span class="ot"&gt; i &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; &lt;span class="dt"&gt;Word8&lt;/span&gt;&lt;br /&gt;        peek_d i &lt;span class="fu"&gt;=&lt;/span&gt; unsafeDupablePerformIO (get i)&lt;br /&gt;        peek_n i &lt;span class="fu"&gt;=&lt;/span&gt; unsafePerformIO        (get i)&lt;br /&gt;        idxes &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;take&lt;/span&gt; &lt;span class="dv"&gt;1024&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt; randomRs (&lt;span class="dv"&gt;0&lt;/span&gt;, sz&lt;span class="fu"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;) (mkStdGen &lt;span class="dv"&gt;49&lt;/span&gt;)&lt;br /&gt;    evaluate (&lt;span class="fu"&gt;sum&lt;/span&gt; idxes)  &lt;span class="co"&gt;-- force idxes ahead of time&lt;/span&gt;&lt;br /&gt;    defaultMain&lt;br /&gt;        [ bench &lt;span class="st"&gt;&amp;quot;dup&amp;quot;&lt;/span&gt;   &lt;span class="fu"&gt;$&lt;/span&gt; nf (&lt;span class="fu"&gt;map&lt;/span&gt; peek_d) idxes&lt;br /&gt;        , bench &lt;span class="st"&gt;&amp;quot;noDup&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt; nf (&lt;span class="fu"&gt;map&lt;/span&gt; peek_n) idxes ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And the results:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;ghc -rtsopts -threaded -O2 peek.hs &amp;amp;&amp;amp; ./peek +RTS -N&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;benchmarking dup&lt;br /&gt;mean: 76.42962 us, lb 75.11134 us, ub 78.18593 us, ci 0.950&lt;br /&gt;std dev: 7.764123 us, lb 6.300310 us, ub 9.790345 us, ci 0.950&lt;br /&gt;&lt;br /&gt;benchmarking noDup&lt;br /&gt;mean: 142.1720 us, lb 139.7312 us, ub 145.4300 us, ci 0.950&lt;br /&gt;std dev: 14.43673 us, lb 11.40254 us, ub 17.86663 us, ci 0.950&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So performance-critical &lt;a href="http://en.wikipedia.org/wiki/Idempotence"&gt;idempotent&lt;/a&gt; actions can benefit from &lt;code&gt;unsafeDupablePerformIO&lt;/code&gt;. But most code should use the safer &lt;code&gt;unsafePerformIO&lt;/code&gt;, as our bug reproducer does. And the &lt;code&gt;noDuplicate#&lt;/code&gt; machinery for &lt;code&gt;unsafePerformIO&lt;/code&gt; makes sense, so what's causing our bug?&lt;/p&gt;&lt;h1 id="the-bug-finally"&gt;The bug, finally&lt;/h1&gt;&lt;p&gt;After all those details and diversions, let's go back to &lt;a href="http://hackage.haskell.org/trac/ghc/changeset/96c80d34163fd422cbc18f4532b7556212a554b8"&gt;the fix&lt;/a&gt; for &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/5558"&gt;GHC bug #5558&lt;/a&gt;. The action is mostly in &lt;a href="http://hackage.haskell.org/trac/ghc/changeset/96c80d34163fd422cbc18f4532b7556212a554b8/rts/sm/Storage.c"&gt;&lt;code&gt;rts/sm/Storage.c&lt;/code&gt;&lt;/a&gt;. This file is part of GHC's &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage"&gt;storage manager&lt;/a&gt;, which provides services such as garbage collection.&lt;/p&gt;&lt;p&gt;Recall that our problematic code looked like this:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;ioThunk &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; ()&lt;br /&gt;ioThunk &lt;span class="fu"&gt;=&lt;/span&gt; unsafePerformIO &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt; &lt;span class="fu"&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is an application of the function &lt;code&gt;($)&lt;/code&gt; to the argument &lt;code&gt;unsafePerformIO&lt;/code&gt;. So it's a static thunk, a CAF. Here's the &lt;em&gt;old&lt;/em&gt; description of how CAF evaluation works, &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/sm/Storage.c?rev=e91ed183fdde4aa4f51b96987c7fb6fa2bfd15f5#L227"&gt;from &lt;code&gt;Storage.c&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The entry code for every CAF does the following:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;builds a &lt;code&gt;BLACKHOLE&lt;/code&gt; in the heap&lt;/li&gt;&lt;li&gt;pushes an update frame pointing to the &lt;code&gt;BLACKHOLE&lt;/code&gt;&lt;/li&gt;&lt;li&gt;calls &lt;code&gt;newCaf&lt;/code&gt;, below&lt;/li&gt;&lt;li&gt;updates the CAF with a static indirection to the &lt;code&gt;BLACKHOLE&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Why do we build an &lt;code&gt;BLACKHOLE&lt;/code&gt; in the heap rather than just updating the thunk directly? It's so that we only need one kind of update frame - otherwise we'd need a static version of the update frame too.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So here's the problem. Normal thunks get blackholed &lt;em&gt;in place&lt;/em&gt;, and a thread detects duplicated evaluation by noticing that one of its thunks-in-progress became a &lt;code&gt;BLACKHOLE&lt;/code&gt;. But static thunks — CAFs — are blackholed &lt;em&gt;by indirection&lt;/em&gt;. Two threads might perform the above procedure concurrently, producing two different heap-allocated &lt;code&gt;BLACKHOLE&lt;/code&gt;s, and they'd never notice.&lt;/p&gt;&lt;p&gt;As Simon Marlow put it:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Note [&lt;em&gt;atomic CAF entry&lt;/em&gt;]&lt;/p&gt;&lt;p&gt;With &lt;code&gt;THREADED_RTS&lt;/code&gt;, &lt;code&gt;newCaf()&lt;/code&gt; is required to be atomic (see #5558). This is because if two threads happened to enter the same CAF simultaneously, they would create two distinct &lt;code&gt;CAF_BLACKHOLEs&lt;/code&gt;, and so the normal &lt;code&gt;threadPaused()&lt;/code&gt; machinery for detecting duplicate evaluation will not detect this. Hence in &lt;code&gt;lockCAF()&lt;/code&gt; below, we atomically lock the CAF with &lt;code&gt;WHITEHOLE&lt;/code&gt; before updating it with &lt;code&gt;IND_STATIC&lt;/code&gt;, and return zero if another thread locked the CAF first. In the event that we lost the race, CAF entry code will re-enter the CAF and block on the other thread's &lt;code&gt;CAF_BLACKHOLE&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I can't explain precisely what a &lt;code&gt;WHITEHOLE&lt;/code&gt; means, but they're used for &lt;a href="http://en.wikipedia.org/wiki/Spinlock"&gt;spin locks&lt;/a&gt; or wait-free synchronization in various places. For example, the &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/PrimOps.cmm?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L1105"&gt;&lt;code&gt;MVar&lt;/code&gt; primitives&lt;/a&gt; are synchronized by the &lt;a href="http://hackage.haskell.org/trac/ghc/browser/includes/rts/storage/SMPClosureOps.h?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L26"&gt;&lt;code&gt;lockClosure&lt;/code&gt;&lt;/a&gt; spinlock routine, which uses &lt;code&gt;WHITEHOLE&lt;/code&gt;s.&lt;/p&gt;&lt;h1 id="the-fix"&gt;The fix&lt;/h1&gt;&lt;p&gt;Here's the corrected &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/sm/Storage.c?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L227"&gt;CAF evaluation procedure&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The entry code for every CAF does the following:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;builds a &lt;code&gt;CAF_BLACKHOLE&lt;/code&gt; in the heap&lt;/li&gt;&lt;li&gt;calls &lt;code&gt;newCaf&lt;/code&gt;, which atomically updates the CAF with &lt;code&gt;IND_STATIC&lt;/code&gt; pointing to the &lt;code&gt;CAF_BLACKHOLE&lt;/code&gt;&lt;/li&gt;&lt;li&gt;if &lt;code&gt;newCaf&lt;/code&gt; returns zero, it re-enters the CAF (see Note [&lt;em&gt;atomic CAF entry&lt;/em&gt;])&lt;/li&gt;&lt;li&gt;pushes an update frame pointing to the &lt;code&gt;CAF_BLACKHOLE&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;code&gt;newCAF&lt;/code&gt; is made atomic by introducing a new helper function, &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/sm/Storage.c?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L293"&gt;&lt;code&gt;lockCAF&lt;/code&gt;&lt;/a&gt;, which is reproduced here for your viewing pleasure:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;STATIC_INLINE StgWord lockCAF (StgClosure *caf, StgClosure *bh)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="dt"&gt;const&lt;/span&gt; StgInfoTable *orig_info;&lt;br /&gt;&lt;br /&gt;    orig_info = caf-&amp;gt;header.info;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;#ifdef THREADED_RTS&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;const&lt;/span&gt; StgInfoTable *cur_info;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (orig_info == &amp;amp;stg_IND_STATIC_info ||&lt;br /&gt;        orig_info == &amp;amp;stg_WHITEHOLE_info) {&lt;br /&gt;        &lt;span class="co"&gt;// already claimed by another thread; re-enter the CAF&lt;/span&gt;&lt;br /&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    cur_info = (&lt;span class="dt"&gt;const&lt;/span&gt; StgInfoTable *)&lt;br /&gt;        cas((StgVolatilePtr)&amp;amp;caf-&amp;gt;header.info,&lt;br /&gt;            (StgWord)orig_info,&lt;br /&gt;            (StgWord)&amp;amp;stg_WHITEHOLE_info);&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;if&lt;/span&gt; (cur_info != orig_info) {&lt;br /&gt;        &lt;span class="co"&gt;// already claimed by another thread; re-enter the CAF&lt;/span&gt;&lt;br /&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="co"&gt;// successfully claimed by us; overwrite with IND_STATIC&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="co"&gt;// For the benefit of revertCAFs(), save the original info pointer&lt;/span&gt;&lt;br /&gt;    ((StgIndStatic *)caf)-&amp;gt;saved_info  = orig_info;&lt;br /&gt;&lt;br /&gt;    ((StgIndStatic*)caf)-&amp;gt;indirectee = bh;&lt;br /&gt;    write_barrier();&lt;br /&gt;    SET_INFO(caf,&amp;amp;stg_IND_STATIC_info);&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We grab the CAF's &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#HeapObjects"&gt;info table pointer&lt;/a&gt;, which tells us what kind of object it is. If it's not already claimed by another thread, we write a &lt;code&gt;WHITEHOLE&lt;/code&gt; — but only if the CAF hasn't changed in the meantime. This step is an atomic &lt;a href="http://en.wikipedia.org/wiki/Compare-and-swap"&gt;compare-and-swap&lt;/a&gt;, implemented by architecture-specific code. The function &lt;code&gt;cas&lt;/code&gt; is &lt;a href="http://hackage.haskell.org/trac/ghc/browser/includes/stg/SMP.h?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L43"&gt;specified by this pseudocode&lt;/a&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;cas(p,o,n) {&lt;br /&gt;   &lt;span class="kw"&gt;atomically&lt;/span&gt; {&lt;br /&gt;      r = *p;&lt;br /&gt;      &lt;span class="kw"&gt;if&lt;/span&gt; (r == o) { *p = n };&lt;br /&gt;      &lt;span class="kw"&gt;return&lt;/span&gt; r;&lt;br /&gt;   }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here's the &lt;a href="http://hackage.haskell.org/trac/ghc/browser/includes/stg/SMP.h?rev=96c80d34163fd422cbc18f4532b7556212a554b8#L165"&gt;implementation for x86&lt;/a&gt;, using &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html"&gt;GCC extended inline assembly&lt;/a&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode c"&gt;EXTERN_INLINE StgWord&lt;br /&gt;cas(StgVolatilePtr p, StgWord o, StgWord n)&lt;br /&gt;{&lt;br /&gt;    __asm__ __volatile__ (&lt;br /&gt;          &lt;span class="st"&gt;&amp;quot;lock&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;cmpxchg %3,%1&amp;quot;&lt;/span&gt;&lt;br /&gt;          :&lt;span class="st"&gt;&amp;quot;=a&amp;quot;&lt;/span&gt;(o), &lt;span class="st"&gt;&amp;quot;=m&amp;quot;&lt;/span&gt; (*(&lt;span class="dt"&gt;volatile&lt;/span&gt; &lt;span class="dt"&gt;unsigned&lt;/span&gt; &lt;span class="dt"&gt;int&lt;/span&gt; *)p)&lt;br /&gt;          :&lt;span class="st"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; (o), &lt;span class="st"&gt;&amp;quot;r&amp;quot;&lt;/span&gt; (n));&lt;br /&gt;    &lt;span class="kw"&gt;return&lt;/span&gt; o;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are some interesting variations between architectures. SPARC and x86 use single instructions, while PowerPC and ARMv6 have longer sequences. Old ARM processors require a &lt;a href="http://hackage.haskell.org/trac/ghc/browser/rts/OldARMAtomic.c?rev=96c80d34163fd422cbc18f4532b7556212a554b8"&gt;global spinlock&lt;/a&gt;, which sounds painful. Who's running Haskell on ARMv5 chips?&lt;/p&gt;&lt;h1 id="deep-breath"&gt;*deep breath*&lt;/h1&gt;&lt;p&gt;Thanks for reading / skimming this far! I learned a lot by writing this article, and I hope you enjoyed reading it. I'm sure I said something wrong somewhere, so please do not hesitate to correct me in the comments.&lt;/p&gt;&lt;div class="footnotes"&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id="x1fn1"&gt;&lt;p&gt;Tim Harris, Simon Marlow, and Simon Peyton Jones. &lt;a href="http://www.haskell.org/~simonmar/papers/multiproc.pdf"&gt;Haskell on a shared-memory multiprocessor&lt;/a&gt;. In Haskell '05: Proceedings of the 2005 ACM SIGPLAN workshop on Haskell, pages 49–61. &lt;a href="#x1fnref1" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li id="x1fn2"&gt;&lt;p&gt;Simon Marlow, Simon Peyton Jones, and Satnam Singh. &lt;a href="http://community.haskell.org/~simonmar/papers/multicore-ghc.pdf"&gt;Runtime Support for Multicore Haskell&lt;/a&gt;. In ICFP'09. &lt;a href="#x1fnref2" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-7170898440757064828?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/7170898440757064828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/thunks-and-lazy-blackholes-introduction.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7170898440757064828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7170898440757064828'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/thunks-and-lazy-blackholes-introduction.html' title='Thunks and lazy blackholes: an introduction to GHC at runtime'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-6928229221680423915</id><published>2011-10-24T19:48:00.000-07:00</published><updated>2011-10-24T19:48:01.979-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='repa'/><category scheme='http://www.blogger.com/atom/ns#' term='quasicrystal'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Quasicrystals as sums of waves in the plane</title><content type='html'>&lt;p&gt;On the suggestion of &lt;a href="http://wealoneonearth.blogspot.com/search/label/quasicrystal"&gt;a friend&lt;/a&gt;, I rendered this animation:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i.imgur.com/l3LL3.gif" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="512" width="512" src="http://i.imgur.com/l3LL3.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;This &lt;a href="http://en.wikipedia.org/wiki/Quasicrystal"&gt;quasicrystal&lt;/a&gt; is full of emergent patterns, but it can be described in a simple way. Imagine that every point in the plane is shaded according to the cosine of its &lt;em&gt;y&lt;/em&gt; coordinate. The result would look like this:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-j2k8sR7KXrk/TqYcYCP0lwI/AAAAAAAAACg/EFbCg-re7-w/s1600/1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="192" width="192" src="http://1.bp.blogspot.com/-j2k8sR7KXrk/TqYcYCP0lwI/AAAAAAAAACg/EFbCg-re7-w/s400/1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Now we can rotate this image to get other waves, like these:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-nxFlY_0BNVc/TqYcedwQXdI/AAAAAAAAACs/_VvOLNoPEio/s1600/2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="192" width="192" src="http://2.bp.blogspot.com/-nxFlY_0BNVc/TqYcedwQXdI/AAAAAAAAACs/_VvOLNoPEio/s400/2.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/-dUz8KnKdIdY/TqYchJMyOpI/AAAAAAAAAC4/kT7Gl3lIMqI/s1600/3.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="192" width="192" src="http://3.bp.blogspot.com/-dUz8KnKdIdY/TqYchJMyOpI/AAAAAAAAAC4/kT7Gl3lIMqI/s400/3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Each frame of the animation is a summation of such waves at evenly-spaced rotations. The animation occurs as each wave moves forward.&lt;/p&gt;&lt;p&gt;I recommend viewing it up close, and then from a few feet back. There are different patterns at each spatial scale.&lt;/p&gt;&lt;h1 id="the-code"&gt;The code&lt;/h1&gt;&lt;p&gt;To render this animation I wrote a Haskell program, using the &lt;a href="http://repa.ouroborus.net/"&gt;Repa&lt;/a&gt; array library. For my purposes, the advantages of Repa are:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;Immutable arrays, supporting clean, expressive code&lt;/li&gt;&lt;li&gt;A fast implementation, including automatic parallelization&lt;/li&gt;&lt;li&gt;Easy output to image files, via &lt;a href="http://hackage.haskell.org/package/repa-devil"&gt;&lt;code&gt;repa-devil&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here is a simplified (but complete!) program, which renders a single still image.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Array.Repa&lt;/span&gt; ( &lt;span class="dt"&gt;Array&lt;/span&gt;, &lt;span class="dt"&gt;DIM2&lt;/span&gt;, &lt;span class="dt"&gt;DIM3&lt;/span&gt;, &lt;span class="dt"&gt;Z&lt;/span&gt;(&lt;span class="fu"&gt;..&lt;/span&gt;), (&lt;span class="fu"&gt;:.&lt;/span&gt;)(&lt;span class="fu"&gt;..&lt;/span&gt;) )&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Array.Repa&lt;/span&gt;          &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Array.Repa.IO.DevIL&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;D&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Word&lt;/span&gt;  ( &lt;span class="dt"&gt;Word8&lt;/span&gt;   )&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Fixed&lt;/span&gt; ( divMod' )&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For clarity, we define a few type synonyms:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;     &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Float&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt;    &lt;span class="fu"&gt;=&lt;/span&gt; (&lt;span class="dt"&gt;R&lt;/span&gt;, &lt;span class="dt"&gt;R&lt;/span&gt;)&lt;br /&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Angle&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We'll convert pixel indices to coordinates in the real plane, with origin at the image center. We have to decide how many pixels to draw, and how much of the plane to show.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;pixels &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;br /&gt;pixels &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;800&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;scale &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;&lt;br /&gt;scale &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;128&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Repa's array indices are &amp;quot;snoc lists&amp;quot; of the form &lt;code&gt;(Z :. x :.  y)&lt;/code&gt;. By contrast, our planar coordinates are conventional tuples.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;point &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;DIM2&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt;&lt;br /&gt;point &lt;span class="fu"&gt;=&lt;/span&gt; \(&lt;span class="dt"&gt;Z&lt;/span&gt; &lt;span class="fu"&gt;:.&lt;/span&gt; x &lt;span class="fu"&gt;:.&lt;/span&gt; y) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (adj x, adj y) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    adj n &lt;span class="fu"&gt;=&lt;/span&gt; scale &lt;span class="fu"&gt;*&lt;/span&gt; ((&lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="fu"&gt;*&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; n &lt;span class="fu"&gt;/&lt;/span&gt; denom) &lt;span class="fu"&gt;-&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;br /&gt;    denom &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; pixels &lt;span class="fu"&gt;-&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A single wave is a cosine depending on &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; coordinates in some proportion, determined by the wave's orientation angle.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;wave &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Angle&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;&lt;br /&gt;wave th &lt;span class="fu"&gt;=&lt;/span&gt; f &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    (cth, sth) &lt;span class="fu"&gt;=&lt;/span&gt; (&lt;span class="fu"&gt;cos&lt;/span&gt; th, &lt;span class="fu"&gt;sin&lt;/span&gt; th)&lt;br /&gt;    f (x,y) &lt;span class="fu"&gt;=&lt;/span&gt; (&lt;span class="fu"&gt;cos&lt;/span&gt; (cth&lt;span class="fu"&gt;*&lt;/span&gt;x &lt;span class="fu"&gt;+&lt;/span&gt; sth&lt;span class="fu"&gt;*&lt;/span&gt;y) &lt;span class="fu"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;) &lt;span class="fu"&gt;/&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To combine several functions, we sum their outputs, and wrap to produce a result between 0 and 1. As &lt;code&gt;n&lt;/code&gt; increases, &lt;code&gt;(wrap n)&lt;/code&gt; will rise to 1, fall back to 0, rise again, and so on. &lt;code&gt;sequence&lt;/code&gt; converts a list of functions to a function returning a list, using the monad instance for &lt;code&gt;((-&amp;gt;) r)&lt;/code&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;combine &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; [&lt;span class="dt"&gt;R2&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;R2&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;)&lt;br /&gt;combine xs &lt;span class="fu"&gt;=&lt;/span&gt; wrap &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;sum&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;sequence&lt;/span&gt; xs &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    wrap n &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;case&lt;/span&gt; divMod' n &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="kw"&gt;of&lt;/span&gt;&lt;br /&gt;        (k, v) &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;odd&lt;/span&gt; k     &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="fu"&gt;-&lt;/span&gt;v&lt;br /&gt;               &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;otherwise&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; v&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To draw the quasicrystal, we combine waves at 7 angles evenly spaced between 0 and &lt;em&gt;π&lt;/em&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;angles &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [&lt;span class="dt"&gt;Angle&lt;/span&gt;]&lt;br /&gt;angles n &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;take&lt;/span&gt; n &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;enumFromThen&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt; (&lt;span class="fu"&gt;pi&lt;/span&gt; &lt;span class="fu"&gt;/&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; n)&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;quasicrystal &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;DIM2&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt;&lt;br /&gt;quasicrystal &lt;span class="fu"&gt;=&lt;/span&gt; combine (&lt;span class="fu"&gt;map&lt;/span&gt; wave (angles &lt;span class="dv"&gt;7&lt;/span&gt;)) &lt;span class="fu"&gt;.&lt;/span&gt; point&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We convert an array of floating-point values to an image in two steps. First, we map floats in [0,1] to bytes in [0,255]. Then we copy this to every color channel. The result is a 3-dimensional array, indexed by (row, column, channel). &lt;code&gt;repa-devil&lt;/code&gt; takes such an array and outputs a PNG image file.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;toImage &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Array&lt;/span&gt; &lt;span class="dt"&gt;DIM2&lt;/span&gt; &lt;span class="dt"&gt;R&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Array&lt;/span&gt; &lt;span class="dt"&gt;DIM3&lt;/span&gt; &lt;span class="dt"&gt;Word8&lt;/span&gt;&lt;br /&gt;toImage arr &lt;span class="fu"&gt;=&lt;/span&gt; R.traverse arr8 (&lt;span class="fu"&gt;:.&lt;/span&gt; &lt;span class="dv"&gt;4&lt;/span&gt;) chans &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    arr8 &lt;span class="fu"&gt;=&lt;/span&gt; R.map (&lt;span class="fu"&gt;floor&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; (&lt;span class="fu"&gt;*&lt;/span&gt;&lt;span class="dv"&gt;255&lt;/span&gt;) &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;min&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;max&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;) arr&lt;br /&gt;    chans _ (&lt;span class="dt"&gt;Z&lt;/span&gt; &lt;span class="fu"&gt;:.&lt;/span&gt; _ &lt;span class="fu"&gt;:.&lt;/span&gt; _ &lt;span class="fu"&gt;:.&lt;/span&gt; &lt;span class="dv"&gt;3&lt;/span&gt;) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;255&lt;/span&gt;  &lt;span class="co"&gt;-- alpha channel&lt;/span&gt;&lt;br /&gt;    chans a (&lt;span class="dt"&gt;Z&lt;/span&gt; &lt;span class="fu"&gt;:.&lt;/span&gt; x &lt;span class="fu"&gt;:.&lt;/span&gt; y &lt;span class="fu"&gt;:.&lt;/span&gt; _) &lt;span class="fu"&gt;=&lt;/span&gt; a (&lt;span class="dt"&gt;Z&lt;/span&gt; &lt;span class="fu"&gt;:.&lt;/span&gt; x &lt;span class="fu"&gt;:.&lt;/span&gt; y)&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;main &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; arr &lt;span class="fu"&gt;=&lt;/span&gt; R.fromFunction (&lt;span class="dt"&gt;Z&lt;/span&gt; &lt;span class="fu"&gt;:.&lt;/span&gt; pixels &lt;span class="fu"&gt;:.&lt;/span&gt; pixels) quasicrystal&lt;br /&gt;    D.runIL &lt;span class="fu"&gt;$&lt;/span&gt; D.writeImage &lt;span class="st"&gt;&amp;quot;out.png&amp;quot;&lt;/span&gt; (toImage arr)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="running-it"&gt;Running it&lt;/h1&gt;&lt;p&gt;Repa's array operations automatically run in parallel. We just need to enable GHC's threaded runtime.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;ghc -O2 -rtsopts -threaded quasicrystal.lhs&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;./quasicrystal +RTS -N&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;xview out.png&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And it looks like this:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-uMAuBageeA0/TqYf-_8zGbI/AAAAAAAAAD0/UTttetA2Eik/s1600/ul800.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="640" width="640" src="http://3.bp.blogspot.com/-FA3Zv8Lh44o/TqYfyMEmiuI/AAAAAAAAADo/pRJKxpNM9JQ/s640/ul640.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Note that &lt;code&gt;repa-devil&lt;/code&gt; silently refuses to overwrite an existing file, so you may need to &lt;code&gt;rm out.png&lt;/code&gt; first.&lt;/p&gt;&lt;p&gt;On my 6-core machine, this parallel code ran in 3.72 seconds of wall-clock time, at a CPU utilization of 474%. The same code compiled without &lt;code&gt;-threaded&lt;/code&gt; took 14.20 seconds, so the net efficiency of parallelization is 382%. This is a good result; what's better is how little work it required on my part. Cutting a mere 10 seconds from a single run is not a big deal. But it starts to matter when rendering many frames of animation, and trying out variations on the algorithm.&lt;/p&gt;&lt;p&gt;As a side note, switching from &lt;code&gt;Float&lt;/code&gt; to &lt;code&gt;Double&lt;/code&gt; increased the run time by about 30%. I suspect this is due to increased demand for memory bandwidth and cache space.&lt;/p&gt;&lt;p&gt;You can grab the &lt;a href="https://github.com/kmcallister/blog-misc/blob/master/quasicrystals/quasicrystal.lhs"&gt;Literate Haskell source&lt;/a&gt; and try it out on your own machine. This is my first Repa program ever, so I'd much appreciate feedback on improving the code.&lt;/p&gt;&lt;p&gt;Be sure to check out &lt;a href="http://wealoneonearth.blogspot.com/search/label/quasicrystal"&gt;Michael Rule&lt;/a&gt;'s work on animating quasicrystals.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-6928229221680423915?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/6928229221680423915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/quasicrystals-as-sums-of-waves-in-plane.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6928229221680423915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6928229221680423915'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/quasicrystals-as-sums-of-waves-in-plane.html' title='Quasicrystals as sums of waves in the plane'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-j2k8sR7KXrk/TqYcYCP0lwI/AAAAAAAAACg/EFbCg-re7-w/s72-c/1.png' height='72' width='72'/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-5732589866656078741</id><published>2011-10-21T01:12:00.000-07:00</published><updated>2011-10-21T01:14:57.065-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='tsp'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='concorde'/><title type='text'>Interfacing Haskell to the Concorde solver for Traveling Salesperson Problem</title><content type='html'>&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Travelling_salesman_problem"&gt;Traveling Salesperson Problem&lt;/a&gt; (TSP) is a famous optimization problem with applications in logistics, manufacturing, and &lt;a href="http://www.cgl.uwaterloo.ca/~csk/projects/tsp/"&gt;art&lt;/a&gt;. In its &lt;a href="http://en.wikipedia.org/wiki/Euclidean_traveling_salesman_problem#Euclidean_TSP"&gt;planar form&lt;/a&gt;, we are given a set of &amp;quot;cities&amp;quot;, and we want to visit each city while minimizing the total travel distance.&lt;/p&gt;&lt;p&gt;Finding the shortest possible tour is &lt;a href="http://en.wikipedia.org/wiki/NP-hard"&gt;NP-hard&lt;/a&gt;, and quickly becomes infeasible as the number of cities grows. But most applications need only a heuristically good solution: a tour which is short, if not the shortest possible. The &lt;a href="http://en.wikipedia.org/wiki/Lin%E2%80%93Kernighan_heuristic"&gt;Lin-Kernighan heuristic&lt;/a&gt; quickly produces such tours.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://www.tsp.gatech.edu/concorde.html"&gt;Concorde&lt;/a&gt; project provides a &lt;a href="http://www.jstatsoft.org/v23/i02"&gt;well-regarded&lt;/a&gt; collection of TSP solvers. I needed TSP heuristics for a Haskell project, so I wrote a &lt;a href="http://hackage.haskell.org/package/concorde"&gt;Haskell interface&lt;/a&gt; to Concorde's Lin-Kernighan implementation. Concorde provides a &lt;a href="http://www.tsp.gatech.edu/concorde/DOC/concorde_org.html"&gt;C library&lt;/a&gt;, but it's far from clear how to use it. Instead I chose to invoke the &lt;code&gt;linkern&lt;/code&gt; executable as a subprocess.&lt;/p&gt;&lt;p&gt;The core of the Haskell interface looks like this:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;tsp&lt;br /&gt;&lt;span class="ot"&gt;  &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Config&lt;/span&gt;     &lt;span class="co"&gt;-- provides various configurable parameters&lt;/span&gt;&lt;br /&gt;  &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt;)  &lt;span class="co"&gt;-- gives the rectangular coordinates of each point&lt;/span&gt;&lt;br /&gt;  &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [a]        &lt;span class="co"&gt;-- list of points to visit&lt;/span&gt;&lt;br /&gt;  &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; [a]     &lt;span class="co"&gt;-- produces points permuted in tour order&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tsp&lt;/code&gt; lets you represent the points to visit using any type you like. You just provide a function to get the coordinates of each point. The &lt;code&gt;Config&lt;/code&gt; parameter controls various aspects of the computation, including the time/quality tradeoff. Defaults are provided, and you can override these selectively using record-update syntax. All considered it's a pretty simple interface which tries to hide the complexity of interacting with an external program.&lt;/p&gt;&lt;h1 id="visualizing-a-tour"&gt;Visualizing a tour&lt;/h1&gt;&lt;p&gt;Here's a example program which computes a tour of 1,000 random points. We'll visualize the tour using the &lt;a href="http://projects.haskell.org/diagrams/"&gt;Diagrams&lt;/a&gt; library.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Diagrams.Prelude&lt;/span&gt;&lt;br /&gt;    ( &lt;span class="dt"&gt;Diagram&lt;/span&gt;  , &lt;span class="dt"&gt;Point&lt;/span&gt;(&lt;span class="dt"&gt;P&lt;/span&gt;), fillColor   , lineWidth&lt;br /&gt;    , translate, circle  , fromVertices, lightgrey )&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Diagrams.Backend.Cairo.CmdLine&lt;/span&gt;&lt;br /&gt;    ( &lt;span class="dt"&gt;Cairo&lt;/span&gt;, defaultMain )&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Colour.SRGB&lt;/span&gt;         ( sRGB       )&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Colour.RGBSpace&lt;/span&gt;     ( uncurryRGB )&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Colour.RGBSpace.HSV&lt;/span&gt; ( hsv        )&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Algorithms.Concorde.LinKern&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;T&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Monad&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Monoid&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.Random&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tsp&lt;/code&gt; takes a list of points and a function to extract the coordinates of a point. Our points are just the coordinates themselves, so we pass the identity function.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; (&lt;span class="dt"&gt;Double&lt;/span&gt;, &lt;span class="dt"&gt;Double&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;findTour &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; [&lt;span class="dt"&gt;R2&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; [&lt;span class="dt"&gt;R2&lt;/span&gt;]&lt;br /&gt;findTour &lt;span class="fu"&gt;=&lt;/span&gt; T.tsp cfg &lt;span class="fu"&gt;id&lt;/span&gt; &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    cfg &lt;span class="fu"&gt;=&lt;/span&gt; T.defConfig { T.verbose &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;True&lt;/span&gt; }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The tour is drawn as a loop of line segements. We also shade the interior of this polygon.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;diaTour &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; [&lt;span class="dt"&gt;R2&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Diagram&lt;/span&gt; &lt;span class="dt"&gt;Cairo&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt;&lt;br /&gt;diaTour xs&lt;span class="fu"&gt;@&lt;/span&gt;(x&lt;span class="fu"&gt;:&lt;/span&gt;_) &lt;span class="fu"&gt;=&lt;/span&gt; sty &lt;span class="fu"&gt;.&lt;/span&gt; fromVertices &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; &lt;span class="dt"&gt;P&lt;/span&gt; (xs &lt;span class="fu"&gt;++&lt;/span&gt; [x]) &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    sty &lt;span class="fu"&gt;=&lt;/span&gt; fillColor lightgrey &lt;span class="fu"&gt;.&lt;/span&gt; lineWidth &lt;span class="dv"&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each point visited by the tour is drawn as a circle, with hue indicating its position in the tour.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;diaPoints &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; [&lt;span class="dt"&gt;R2&lt;/span&gt;] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Diagram&lt;/span&gt; &lt;span class="dt"&gt;Cairo&lt;/span&gt; &lt;span class="dt"&gt;R2&lt;/span&gt;&lt;br /&gt;diaPoints &lt;span class="fu"&gt;=&lt;/span&gt; mconcat &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;map&lt;/span&gt; circ &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;zip&lt;/span&gt; [&lt;span class="dv"&gt;0&lt;/span&gt;&lt;span class="fu"&gt;..&lt;/span&gt;] &lt;span class="kw"&gt;where&lt;/span&gt;&lt;br /&gt;    n &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;fromIntegral&lt;/span&gt; numPoints&lt;br /&gt;    circ (i,p) &lt;span class="fu"&gt;=&lt;/span&gt; translate p &lt;span class="fu"&gt;.&lt;/span&gt; fillColor color &lt;span class="fu"&gt;$&lt;/span&gt; circle &lt;span class="dv"&gt;40&lt;/span&gt;&lt;br /&gt;        &lt;span class="kw"&gt;where&lt;/span&gt; color &lt;span class="fu"&gt;=&lt;/span&gt; uncurryRGB sRGB (hsv (&lt;span class="dv"&gt;360&lt;/span&gt;&lt;span class="fu"&gt;*&lt;/span&gt;i&lt;span class="fu"&gt;/&lt;/span&gt;n) &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we put it all together. Note that &lt;code&gt;linkern&lt;/code&gt; uses Euclidean distances rounded to the nearest integer. So we need coordinates with fairly large magnitudes. Picking values between 0 and 1 won't work.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;numPoints &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;br /&gt;numPoints &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;1000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;main &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; rnd &lt;span class="fu"&gt;=&lt;/span&gt; randomRIO (&lt;span class="dv"&gt;0&lt;/span&gt;,&lt;span class="dv"&gt;10000&lt;/span&gt;)&lt;br /&gt;    points &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; replicateM numPoints (liftM2 (,) rnd rnd)&lt;br /&gt;    tour   &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; findTour points&lt;br /&gt;    defaultMain (diaPoints tour &lt;span class="ot"&gt;`mappend`&lt;/span&gt; diaTour tour)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We run it like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;export PATH=~/concorde-031219/LINKERN:$PATH&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;runhaskell tour.lhs -o out.pdf&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;xpdf out.pdf&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The computation takes about 2 seconds on my machine. And the output looks like this:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-z4PPQ3F3kvE/TqEoJt-TZkI/AAAAAAAAACE/DgusuBz52kw/s1600/out.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="512" src="http://1.bp.blogspot.com/-z4PPQ3F3kvE/TqEoJt-TZkI/AAAAAAAAACE/DgusuBz52kw/s640/out.png" width="512" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;You can download this post as a &lt;a href="https://github.com/kmcallister/blog-misc/blob/master/concorde/tour.lhs"&gt;Literate Haskell file&lt;/a&gt; and run the above program. You'll need to install the &lt;a href="http://hackage.haskell.org/package/concorde"&gt;&lt;code&gt;concorde&lt;/code&gt;&lt;/a&gt; and &lt;a href="http://hackage.haskell.org/package/diagrams"&gt;&lt;code&gt;diagrams&lt;/code&gt;&lt;/a&gt; packages.&lt;/p&gt;&lt;p&gt;The &lt;a href="https://github.com/kmcallister/concorde"&gt;source&lt;/a&gt; for the &lt;code&gt;concorde&lt;/code&gt; Haskell package includes a &lt;a href="https://github.com/kmcallister/concorde/blob/master/examples/visualize.hs"&gt;more full-featured version&lt;/a&gt; of this example.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-5732589866656078741?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/5732589866656078741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/interfacing-haskell-to-concorde-solver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/5732589866656078741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/5732589866656078741'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/interfacing-haskell-to-concorde-solver.html' title='Interfacing Haskell to the Concorde solver for Traveling Salesperson Problem'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-z4PPQ3F3kvE/TqEoJt-TZkI/AAAAAAAAACE/DgusuBz52kw/s72-c/out.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-8634197994047865596</id><published>2011-10-18T00:18:00.000-07:00</published><updated>2011-10-18T00:18:05.378-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='safe-globals'/><title type='text'>Safe top-level mutable variables for Haskell</title><content type='html'>&lt;p&gt;I uploaded the &lt;a href="http://hackage.haskell.org/package/safe-globals"&gt;&lt;code&gt;safe-globals&lt;/code&gt;&lt;/a&gt; package for Haskell, which lets you declare top-level mutable variables like so:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;{-# LANGUAGE TemplateHaskell #-}&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Global&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.IORef&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;declareIORef &lt;span class="st"&gt;&amp;quot;ref&amp;quot;&lt;/span&gt;&lt;br /&gt;    [t&lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="fu"&gt;|&lt;/span&gt;]&lt;br /&gt;    [e&lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dv"&gt;3&lt;/span&gt;   &lt;span class="fu"&gt;|&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    readIORef  ref &lt;span class="fu"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="fu"&gt;print&lt;/span&gt;  &lt;span class="co"&gt;-- prints 3&lt;/span&gt;&lt;br /&gt;    writeIORef ref &lt;span class="dv"&gt;5&lt;/span&gt;&lt;br /&gt;    readIORef  ref &lt;span class="fu"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="fu"&gt;print&lt;/span&gt;  &lt;span class="co"&gt;-- prints 5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This creates a module-level binding&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;ref &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IORef&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which can be managed through the usual module import/export mechanism.&lt;/p&gt;&lt;h1 id="why-global-state"&gt;Why global state?&lt;/h1&gt;&lt;p&gt;Global state is a sign of bad software design, especially in Haskell. Why would we ever need it? Suppose you're wrapping a C library which is not thread-safe. Using a (hidden!) global lock, you can expose an interface which is simple and safe. In other words, you're using global state to compensate for others using global state.&lt;sup&gt;&lt;a href="#fn1" class="footnoteRef" id="fnref1"&gt;1&lt;/a&gt;&lt;/sup&gt; Another use case is generating unique identifiers to &lt;a href="http://hackage.haskell.org/package/intern"&gt;speed up comparison&lt;/a&gt; of values. This can be done without breaking referential transparency, but you need a source of IDs which is really and truly global.&lt;/p&gt;&lt;p&gt;In these situations it's typical to create global variables using a hack such as&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;ref &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IORef&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt;&lt;br /&gt;ref &lt;span class="fu"&gt;=&lt;/span&gt; unsafePerformIO (newIORef &lt;span class="dv"&gt;3&lt;/span&gt;)&lt;br /&gt;&lt;span class="ot"&gt;{-# NOINLINE ref #-}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My library is just a set of Template Haskell macros for the same hack. If global variables are seldom needed, then what good are these macros?&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;Writing out the hack each time is unsafe. I might forget the &lt;code&gt;NOINLINE&lt;/code&gt; pragma, or subvert the type system with a polymorphic reference. The &lt;code&gt;safe-globals&lt;/code&gt; library prevents these mistakes. I'm of the opinion — and I know it's not shared by all — that even questionable techniques should be made as safe as possible. Call it &amp;quot;harm reduction&amp;quot; if you like.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;In ten years, if GHC 9 requires an extra pragma for safety, then &lt;code&gt;safe-globals&lt;/code&gt; can be updated, without changing every package that uses it. If JHC's &lt;a href="http://repetae.net/computer/jhc/manual2.html#top-level-actions"&gt;ACIO&lt;/a&gt; feature is ported to GHC, then &lt;code&gt;safe-globals&lt;/code&gt; can take advantage and get rid of the hacks entirely.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;But the direct impetus to write &lt;code&gt;safe-globals&lt;/code&gt; was the appearance of the &lt;a href="http://hackage.haskell.org/package/global-variables"&gt;&lt;code&gt;global-variables&lt;/code&gt;&lt;/a&gt; library, which drew some attention in the Haskell community. &lt;code&gt;global-variables&lt;/code&gt; aims to solve the same problem, using a different approach with a number of drawbacks. The rest of this article outlines some of these drawbacks.&lt;/p&gt;&lt;h1 id="spooky-action-at-a-distance"&gt;Spooky action at a distance&lt;/h1&gt;&lt;p&gt;Among the stated features of &lt;code&gt;global-variables&lt;/code&gt; are&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Avoid having to pass references explicitly throughout the program in order to let distant parts communicate. Enable a communication by convention scheme, where e.g. different libraries may communicate without code dependencies.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This refers to the fact that two global refs with the same name string will become entangled, no matter where in a program they were declared. This is certainly a bug, not a feature. Untracked interactions between different components are the archetypal defect in software engineering.&lt;/p&gt;&lt;p&gt;Neither is there a clear way for a user of &lt;code&gt;global-variables&lt;/code&gt; to opt out of this misfeature. The best you can do is augment your names with some prefix which you hope is unique — the same non-solution used by C libraries. Haskell solves namespace problems with a module system and a package system. &lt;code&gt;global-variables&lt;/code&gt; circumvents both.&lt;/p&gt;&lt;p&gt;Still, suppose that you choose &amp;quot;communication by convention&amp;quot; for your library. You'll need to manually document the name and type of every ref used by this communication, since they aren't tracked by the type system. A mismatch (as from a library upgrade) will cause silent breakage. Worse, you need to tell every library user how to initialize your library's own variables, and hope that they do it correctly. When a ref is given different initializers in different declarations, the result is &lt;a href="http://hackage.haskell.org/packages/archive/global-variables/1.0/doc/html/Data-Global.html#g:3"&gt;indeterminate&lt;/a&gt;.&lt;/p&gt;&lt;h1 id="type-clashes"&gt;Type clashes&lt;/h1&gt;&lt;p&gt;A polymorphic reference, with a type like &lt;code&gt;∀ t. IORef t&lt;/code&gt;, breaks the type system. You can write a value of one type and then read it with another type. So it's important for &lt;code&gt;global-variables&lt;/code&gt; to disallow polymorphic refs. The mechanism it uses is that each declaration is implicitly a family of refs, one for each monomorphic type (via &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/base-4.3.1.0/Data-Typeable.html"&gt;&lt;code&gt;Typeable&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Now consider this reasonable-looking program:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;{-# LANGUAGE NoMonomorphismRestriction #-}&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.Global&lt;/span&gt;  &lt;span class="co"&gt;-- from global-variables&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.IORef&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;-- Define the famous factorial function&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;fact &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Integer&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Integer&lt;/span&gt;&lt;br /&gt;fact &lt;span class="dv"&gt;0&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;&lt;br /&gt;fact n &lt;span class="fu"&gt;=&lt;/span&gt; n &lt;span class="fu"&gt;*&lt;/span&gt; fact (n&lt;span class="fu"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;-- Now use it through a global ref&lt;/span&gt;&lt;br /&gt;ref &lt;span class="fu"&gt;=&lt;/span&gt; declareIORef &lt;span class="st"&gt;&amp;quot;ref&amp;quot;&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    writeIORef ref (&lt;span class="fu"&gt;length&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;)&lt;br /&gt;    r &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; readIORef ref&lt;br /&gt;    &lt;span class="fu"&gt;print&lt;/span&gt; (fact r)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will print &lt;code&gt;1&lt;/code&gt;, not &lt;code&gt;120&lt;/code&gt;. The ref is written at type &lt;code&gt;Int&lt;/code&gt; (the return type of &lt;code&gt;length&lt;/code&gt;) and an implicitly different ref is read at type &lt;code&gt;Integer&lt;/code&gt; (because of the subsequent call to &lt;code&gt;fact&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;You can certainly argue that top-level refs should always be declared with a monomorphic type signature. Indeed, my library enforces this. But &lt;code&gt;global-variables&lt;/code&gt; doesn't, and can't. Making type clashes a run-time error would be a step in the right direction.&lt;/p&gt;&lt;div class="footnotes"&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id="fn1"&gt;&lt;p&gt;A common response is that locking should be added in C code; however, concurrent programming in C is cumbersome and dangerous. It's much easier, if a bit ugly, to implement locking on the Haskell side. You could however store an &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/base-4.3.1.0/Control-Concurrent-MVar.html"&gt;&lt;code&gt;MVar&lt;/code&gt;&lt;/a&gt; lock in a C global variable via &lt;a href="http://lambda.haskell.org/hp-tmp/docs/2011.2.0.0/ghc-doc/libraries/haskell2010-1.0.0.0/Foreign-StablePtr.html"&gt;&lt;code&gt;StablePtr&lt;/code&gt;&lt;/a&gt;. Has anyone done this? &lt;a href="#fnref1" class="footnoteBackLink" title="Jump back to footnote 1"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-8634197994047865596?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/8634197994047865596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/safe-top-level-mutable-variables-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8634197994047865596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8634197994047865596'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/safe-top-level-mutable-variables-for.html' title='Safe top-level mutable variables for Haskell'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4870021384817929146</id><published>2011-10-15T15:43:00.000-07:00</published><updated>2011-10-16T00:28:26.650-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='phosphene'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>phosphene: Fractal video feedback as a PC master boot record</title><content type='html'>&lt;p&gt;A few months ago, I wrote a Julia set fractal renderer for the &lt;a href="http://io.smashthestack.org:84/intro/"&gt;demo challenge&lt;/a&gt; hosted by &lt;a href="http://io.smashthestack.org:84/"&gt;&lt;code&gt;io.smashthestack.org&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This program runs in 16-bit x86 real mode, without any operating system. It's formatted as a PC master boot record, which is 512 bytes long. Subtracting out space reserved for a partition table, we have only 446 bytes for code and data.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-sNUVJCyO1ro/TpoLkXgxLNI/AAAAAAAAABU/VMpihB3wWmc/s1600/1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="384" width="512" src="http://3.bp.blogspot.com/-sNUVJCyO1ro/TpoLkXgxLNI/AAAAAAAAABU/VMpihB3wWmc/s640/1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Programming in such a restricted environment is quite a challenge. It's further complicated by real mode's &lt;a href="http://en.wikipedia.org/wiki/X86_memory_segmentation#Real_mode"&gt;segmented addressing&lt;/a&gt;. Indexing an array bigger than 64 kB requires significant extra code — and that goes double for the video frame buffer. With two off-screen buffers and a 640 × 480 × 1 byte video mode, much of my code is devoted to segment juggling.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-DqrGx1SbKLg/TpoLzgvn5uI/AAAAAAAAABg/6qqvvlJSXNY/s1600/4.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="384" width="512" src="http://2.bp.blogspot.com/-DqrGx1SbKLg/TpoLzgvn5uI/AAAAAAAAABg/6qqvvlJSXNY/s640/4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;I spent a long time playing with code compression. In the end, I couldn't find a scheme which justifies the fixed size cost of its own decoder. It seems that 16-bit x86 machine code is actually pretty information-dense. For a bigger demo or 32-bit mode (with bigger immediate operands) I'd definitely want compression.&lt;/p&gt;&lt;p&gt;It's totally feasible to enter 32-bit protected mode within 446 bytes, but there's little gained by doing so. You lose easy access to the PC BIOS, which is the only thing you have that resembles an operating system or standard library.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-s-72MKoMqyw/TpoL4mk64cI/AAAAAAAAABs/C2mQmQeB03U/s1600/5.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="384" width="512" src="http://1.bp.blogspot.com/-s-72MKoMqyw/TpoL4mk64cI/AAAAAAAAABs/C2mQmQeB03U/s640/5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;You can browse the &lt;a href="https://github.com/kmcallister/phosphene/blob/master/phosphene.asm"&gt;assembly source code&lt;/a&gt; or grab the &lt;a href="http://ugcs.net/~keegan/phosphene/phosphene.mbr"&gt;MBR itself&lt;/a&gt;. It runs well in &lt;a href="http://wiki.qemu.org/Main_Page"&gt;QEMU&lt;/a&gt;, with or without &lt;a href="http://www.linux-kvm.org/page/Main_Page"&gt;KVM&lt;/a&gt;, and I also tested it on a few real machines via USB boot.  With QEMU on Linux it's as simple as&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="Prompt"&gt;$&lt;/span&gt; &lt;span class="Entry"&gt;qemu -hda phosphene.mbr&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thanks to Michael Rule for the original idea and for tons of help with tweaking the rendering algorithm. &lt;a href="http://wealoneonearth.blogspot.com/2011/07/instantly-boot-feedback-fractals-with.html"&gt;His writeup&lt;/a&gt; has more information about this project.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4870021384817929146?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4870021384817929146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/phosphene-fractal-video-feedback-as-pc.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4870021384817929146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4870021384817929146'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/phosphene-fractal-video-feedback-as-pc.html' title='phosphene: Fractal video feedback as a PC master boot record'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-sNUVJCyO1ro/TpoLkXgxLNI/AAAAAAAAABU/VMpihB3wWmc/s72-c/1.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-5579869181567964286</id><published>2011-10-12T18:07:00.000-07:00</published><updated>2011-10-12T18:07:38.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='slides'/><title type='text'>Slides from "Why learn Haskell?"</title><content type='html'>&lt;p&gt;Yesterday I gave a talk on the topic of &amp;quot;Why learn Haskell?&amp;quot;, and I've posted the &lt;a href="http://ugcs.net/~keegan/talks/why-learn-haskell/talk.pdf"&gt;slides [PDF]&lt;/a&gt;. Thanks to &lt;a href="http://sipb.mit.edu/"&gt;MIT's SIPB&lt;/a&gt; for organizing &lt;a href="http://cluedumps.mit.edu/wiki/SIPB_Cluedump_Series"&gt;these talks&lt;/a&gt; and providing tasty snacks. Thanks also to the &lt;a href="http://groups.google.com/group/bostonhaskell"&gt;Boston Haskell&lt;/a&gt; group for lots of useful feedback towards improving my talk.&lt;/p&gt;&lt;p&gt;If you'd like to adapt my slides for your own venue, the &lt;a href="http://ugcs.net/~keegan/talks/why-learn-haskell/"&gt;source&lt;/a&gt; is available under a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;CC-By-SA&lt;/a&gt; license. I rendered the PDF using &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/08/new-slides-and-how-i-made-them.html"&gt;pandoc and Beamer&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/1563623855220143059-5579869181567964286?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/5579869181567964286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/slides-from-why-learn-haskell.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/5579869181567964286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/5579869181567964286'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/slides-from-why-learn-haskell.html' title='Slides from &quot;Why learn Haskell?&quot;'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-3358456364450904571</id><published>2011-10-10T13:15:00.000-07:00</published><updated>2011-10-10T13:15:36.398-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='shqq'/><title type='text'>shqq: Embedding shell commands in Haskell code</title><content type='html'>&lt;p&gt;Shell scripts make it easy to pass data between external commands. But shell script as a programming language lacks features like non-trivial data structures and easy, robust concurrency. These would be useful in building quick solutions to system administration and automation problems.&lt;/p&gt;&lt;p&gt;As others have noted,&lt;sup&gt;&lt;a href="http://donsbot.wordpress.com/2010/08/17/practical-haskell/"&gt;1&lt;/a&gt;&lt;a href="http://book.realworldhaskell.org/read/systems-programming-in-haskell.html"&gt;2&lt;/a&gt;&lt;a href="http://changelog.complete.org/archives/587-a-better-environment-for-shell-scripting"&gt;3&lt;/a&gt;&lt;a href="http://blog.ljstech.net/2006/12/shell-tasks-in-haskell.html"&gt;4&lt;/a&gt;&lt;a href="http://blog.mired.org/2011/07/eddie-shell-scripting-with-haskell.html"&gt;5&lt;/a&gt;&lt;/sup&gt; Haskell is an interesting alternative for these scripting tasks. I wrote the &lt;a href="http://hackage.haskell.org/package/shqq"&gt;&lt;code&gt;shqq&lt;/code&gt;&lt;/a&gt; library to make it a little easier to invoke external programs from Haskell. With the &lt;code&gt;sh&lt;/code&gt; &lt;a href="http://www.haskell.org/ghc/docs/7.2-latest/html/users_guide/template-haskell.html#th-quasiquotation"&gt;quasiquoter&lt;/a&gt;, you write a shell command which embeds Haskell variables, execute it as an IO action, and get the command's standard output as a &lt;code&gt;String&lt;/code&gt;. In other words, it's a bit like the backtick operator from Perl or Ruby.&lt;/p&gt;&lt;p&gt;Here's a small example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ ghci -XQuasiQuotes&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;import System.ShQQ&lt;/span&gt;&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;let x = &amp;quot;/proc/uptime&amp;quot; in [sh| sha1sum $x |]&lt;/span&gt;&lt;br /&gt;&amp;quot;337ec3fb998fb3a4650a18e0785f0992762b3cda  /proc/uptime\n&amp;quot;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;shqq&lt;/code&gt; also handles escaping for you, so that the shell will not interpret special characters from Haskell variables. You can override this behavior when desired.&lt;/p&gt;&lt;p&gt;The big caveat is that &lt;code&gt;shqq&lt;/code&gt; refuses to build on GHC 7.0 or earlier, due to a &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/4006"&gt;Unicode-handling bug&lt;/a&gt; in &lt;code&gt;process-1.0&lt;/code&gt;. You'll need GHC 7.2 or later.&lt;/p&gt;&lt;h1 id="finding-duplicate-files"&gt;Finding duplicate files&lt;/h1&gt;&lt;p&gt;As an example, here's a program to find duplicate files in the directory tree rooted at the current working directory.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;{-# LANGUAGE QuasiQuotes, TupleSections #-}&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Concurrent.Spawn&lt;/span&gt;  &lt;span class="co"&gt;-- package spawn-0.3&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Data.List.Split&lt;/span&gt;           &lt;span class="co"&gt;-- package split-0.1&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.ShQQ&lt;/span&gt;               &lt;span class="co"&gt;-- package shqq-0.1&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;System.Posix.Files&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Map&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, the computation itself. If we pair each file with a key, such as size or checksum, we can find the groups of (potentially) duplicate files.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;dupes &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; (&lt;span class="kw"&gt;Ord&lt;/span&gt; k) &lt;span class="ot"&gt;=&amp;gt;&lt;/span&gt; [(&lt;span class="fu"&gt;FilePath&lt;/span&gt;,k)] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [[&lt;span class="fu"&gt;FilePath&lt;/span&gt;]]&lt;br /&gt;dupes &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;filter&lt;/span&gt; (&lt;span class="fu"&gt;not&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;null&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;drop&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;) &lt;span class="fu"&gt;.&lt;/span&gt; M.elems&lt;br /&gt;      &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;foldr&lt;/span&gt; (\(v,k) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; M.insertWith (&lt;span class="fu"&gt;++&lt;/span&gt;) k [v]) M.empty&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We want to examine files in parallel, but the operating system will complain if we have too many open files. We limit each pass to have at most 256 tests in progress at once.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;inParallel &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; (a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; b) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; [a] &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; [b]&lt;br /&gt;inParallel f xs &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt; p &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; pool &lt;span class="dv"&gt;256&lt;/span&gt;; parMapIO (p &lt;span class="fu"&gt;.&lt;/span&gt; f) xs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For efficiency, we find potential duplicates by size, and then checksum only these files. We use external shell commands for checksumming as well as the initial directory traversal. At the end we print the names of duplicated files, one per line, with a blank line after each group of duplicates.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;main &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;main &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;    files &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; endBy &lt;span class="st"&gt;&amp;quot;\0&amp;quot;&lt;/span&gt; &lt;span class="ot"&gt;`fmap`&lt;/span&gt; &lt;span class="dt"&gt;[sh|&lt;/span&gt;&lt;span class="st"&gt; find -type f -print0 &lt;/span&gt;&lt;span class="dt"&gt;|]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; getSize f &lt;span class="fu"&gt;=&lt;/span&gt; ((f,) &lt;span class="fu"&gt;.&lt;/span&gt; fileSize) &lt;span class="ot"&gt;`fmap`&lt;/span&gt; getFileStatus f&lt;br /&gt;    sizeDupes &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; dupes &lt;span class="ot"&gt;`fmap`&lt;/span&gt; inParallel getSize files&lt;br /&gt;&lt;br /&gt;    &lt;span class="kw"&gt;let&lt;/span&gt; getSha f &lt;span class="fu"&gt;=&lt;/span&gt; ((f,) &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;head&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="fu"&gt;words&lt;/span&gt;) &lt;span class="ot"&gt;`fmap`&lt;/span&gt; &lt;span class="dt"&gt;[sh|&lt;/span&gt;&lt;span class="st"&gt; sha1sum&lt;/span&gt; &lt;span class="ot"&gt;$f&lt;/span&gt; &lt;span class="dt"&gt;|]&lt;/span&gt;&lt;br /&gt;    shaDupes  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; dupes &lt;span class="ot"&gt;`fmap`&lt;/span&gt; inParallel getSha (&lt;span class="fu"&gt;concat&lt;/span&gt; sizeDupes)&lt;br /&gt;&lt;br /&gt;    &lt;span class="fu"&gt;mapM_&lt;/span&gt; (&lt;span class="fu"&gt;mapM_&lt;/span&gt; &lt;span class="fu"&gt;putStrLn&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; (&lt;span class="fu"&gt;++&lt;/span&gt;[&lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt;])) shaDupes&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we run it like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ ghc -O -threaded -rtsopts dupe.hs&lt;br /&gt;$ ./dupe +RTS -N&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I included type signatures for clarity, but you wouldn't need them in a one-off script. Not counting imports and the &lt;code&gt;LANGUAGE&lt;/code&gt; pragma, that makes 10 lines of code total. I'm pretty happy with the expressiveness of this solution, especially the use of parallel IO for an easy speedup.&lt;/p&gt;&lt;p&gt;Thanks to Dylan Lukes for the original idea for this library.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-3358456364450904571?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/3358456364450904571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/shqq-embedding-shell-commands-in.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3358456364450904571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3358456364450904571'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/10/shqq-embedding-shell-commands-in.html' title='shqq: Embedding shell commands in Haskell code'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-305830128874231545</id><published>2011-09-13T21:43:00.000-07:00</published><updated>2011-09-13T21:43:26.001-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='debug-diff'/><title type='text'>debug-diff: Colorized diffs between Haskell values</title><content type='html'>&lt;p&gt;Today I uploaded &lt;a href="http://hackage.haskell.org/package/debug-diff"&gt;a small library&lt;/a&gt; for comparing Haskell values using a textual diff. This has served me well when diagnosing failing tests, or comparing a function with a proposed replacement.&lt;/p&gt; &lt;p&gt;Let's try it on some &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/03/x86-disassembly-in-haskell-with-hdis86.html"&gt;disassembled&lt;/a&gt; x86 code:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ ghci&lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;:m + Hdis86 Debug.Diff Data.ByteString&lt;/span&gt; &lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;let f = disassemble amd64 . pack&lt;/span&gt; &lt;br /&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;diff (f [0x31,0xff,0x41,0x5e,0x48,0x89,0xc7])&lt;/span&gt; &lt;br /&gt;&lt;span class="Entry"&gt;        (f [0x31,0xff,0x41,0x5c,0x48,0x89,0xc7])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;--- /tmp/ddiff_x15061   2011-09-13 22:52:13.911842969 -0400&lt;/span&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;+++ /tmp/ddiff_y15061   2011-09-13 22:52:13.911842969 -0400&lt;/span&gt; &lt;br /&gt;@@ -1,3 +1,3 @@&lt;br /&gt; [Inst [] Ixor [Reg (Reg32 RDI), Reg (Reg32 RDI)],&lt;br /&gt;&lt;span style="color: red;"&gt;- Inst [Rex] Ipop [Reg (Reg64 R14)],&lt;/span&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;+ Inst [Rex] Ipop [Reg (Reg64 R12)],&lt;/span&gt; &lt;br /&gt;  Inst [Rex] Imov [Reg (Reg64 RDI), Reg (Reg64 RAX)]]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;This uses &lt;a href="http://blog.ezyang.com/2010/07/groom-human-readable-show-for-haskell/"&gt;&lt;code&gt;groom&lt;/code&gt;&lt;/a&gt; as a pretty-printer, and shells out to &lt;a href="http://colordiff.sourceforge.net/colordiff.html"&gt;&lt;code&gt;colordiff&lt;/code&gt;&lt;/a&gt; by default.&lt;/p&gt; &lt;p&gt;Sadly, a textual diff does not always produce usable results. I'm also interested in generic diffs for algebraic data types. There are some packages for this (&lt;a href="http://hackage.haskell.org/package/gdiff"&gt;1&lt;/a&gt;, &lt;a href="http://hackage.haskell.org/package/gdiff-ig"&gt;2&lt;/a&gt;) but I haven't yet learned how to use them. This could also be a good application for the &lt;a href="http://www.haskell.org/ghc/docs/7.2-latest/html/users_guide/generic-programming.html"&gt;new generics support&lt;/a&gt; in GHC 7.2.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-305830128874231545?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/305830128874231545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/09/debug-diff-colorized-diffs-between.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/305830128874231545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/305830128874231545'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/09/debug-diff-colorized-diffs-between.html' title='debug-diff: Colorized diffs between Haskell values'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-8605777743951714424</id><published>2011-09-03T15:24:00.000-07:00</published><updated>2011-09-03T15:24:45.501-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='pi-calculus'/><category scheme='http://www.blogger.com/atom/ns#' term='lambda-calculus'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Lambda to pi</title><content type='html'>&lt;!--Copyright (c) Keegan McAllister 2011All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright   notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright   notice, this list of conditions and the following disclaimer in the   documentation and/or other materials provided with the distribution.3. Neither the name of the author nor the names of his contributors   may be used to endorse or promote products derived from this software   without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.--&gt;&lt;p&gt;I gave a talk a while back which included an interpreter for the pi-calculus, and a compiler from the lambda-calculus to it. I didn't really do justice to the material in &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/08/new-slides-and-how-i-made-them.html"&gt;a few slides&lt;/a&gt;, so here's a proper blog post.&lt;/p&gt;&lt;p&gt;This article is &lt;a href="http://ugcs.net/~keegan/code/pi-calc.lhs"&gt;available&lt;/a&gt; as a &lt;a href="http://www.haskell.org/haskellwiki/Literate_programming"&gt;Literate Haskell&lt;/a&gt; file, which you can load into GHCi directly.&lt;/p&gt;&lt;h1 id="the-&amp;#960;-calculus"&gt;The π-calculus&lt;/h1&gt;&lt;p&gt;If the &lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;λ-calculus&lt;/a&gt; is a minimal functional language, then the &lt;a href="http://en.wikipedia.org/wiki/Pi_calculus"&gt;π-calculus&lt;/a&gt; is a minimal concurrent language. There's basically only three things we can do:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;Fork a concurrent thread of execution&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Create message channels and send them through other message channels&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Loop forever&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There's a &lt;a href="http://en.wikipedia.org/wiki/Pi_calculus#Syntax"&gt;conventional syntax&lt;/a&gt; for the π-calculus, which I don't much care for. Since we're writing an interpreter in Haskell, we'll use Haskell datatypes as our only syntax for the π-calculus.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Concurrent&lt;/span&gt;&lt;br /&gt;  (forkIO, &lt;span class="dt"&gt;Chan&lt;/span&gt;, newChan, readChan, writeChan)&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Applicative&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Monad&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="dt"&gt;Control.Monad.State&lt;/span&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; &lt;span class="kw"&gt;qualified&lt;/span&gt; &lt;span class="dt"&gt;Data.Map&lt;/span&gt; &lt;span class="kw"&gt;as&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here's the abstract syntax of the π-calculus:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt; &lt;span class="fu"&gt;:|:&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Rep&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Nil&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;New&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt;      &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Out&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Inp&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Embed&lt;/span&gt; (&lt;span class="dt"&gt;IO&lt;/span&gt; ()) &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Names are bound to message channels, and the only thing we can send through a channel is another channel.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;newtype&lt;/span&gt; &lt;span class="dt"&gt;MuChan&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Wrap&lt;/span&gt; (&lt;span class="dt"&gt;Chan&lt;/span&gt; &lt;span class="dt"&gt;MuChan&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;M.Map&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;MuChan&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Repetition and forking are straightforward:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;run &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Env&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;IO&lt;/span&gt; ()&lt;br /&gt;&lt;br /&gt;run env (&lt;span class="dt"&gt;Rep&lt;/span&gt; p) &lt;span class="fu"&gt;=&lt;/span&gt; forever (run env p)&lt;br /&gt;&lt;br /&gt;run env (a &lt;span class="fu"&gt;:|:&lt;/span&gt; b) &lt;span class="fu"&gt;=&lt;/span&gt;&lt;br /&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; f &lt;span class="fu"&gt;=&lt;/span&gt; forkIO &lt;span class="fu"&gt;.&lt;/span&gt; run env&lt;br /&gt;  &lt;span class="kw"&gt;in&lt;/span&gt;  f a &lt;span class="fu"&gt;&amp;gt;&amp;gt;&lt;/span&gt; f b &lt;span class="fu"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="fu"&gt;return&lt;/span&gt; ()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also have a base-case program that does nothing:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;run _ &lt;span class="dt"&gt;Nil&lt;/span&gt; &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;return&lt;/span&gt; ()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we have three operations on channels. &lt;code&gt;(New bind p)&lt;/code&gt; creates a new channel, binds it to the local name &lt;code&gt;bind&lt;/code&gt;, then does &lt;code&gt;p&lt;/code&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;run env (&lt;span class="dt"&gt;New&lt;/span&gt; bind p) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  c &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="dt"&gt;Wrap&lt;/span&gt; &lt;span class="fu"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; newChan&lt;br /&gt;  run (M.insert bind c env) p&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;(Out dest msg p)&lt;/code&gt; sends the channel &lt;code&gt;msg&lt;/code&gt; to the channel &lt;code&gt;dest&lt;/code&gt;, then does &lt;code&gt;p&lt;/code&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;run env (&lt;span class="dt"&gt;Out&lt;/span&gt; dest msg p) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; &lt;span class="dt"&gt;Wrap&lt;/span&gt; c &lt;span class="fu"&gt;=&lt;/span&gt; env &lt;span class="fu"&gt;M.!&lt;/span&gt; dest&lt;br /&gt;  writeChan c (env &lt;span class="fu"&gt;M.!&lt;/span&gt; msg)&lt;br /&gt;  run env p&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;(Inp src bind p)&lt;/code&gt; reads a channel from &lt;code&gt;src&lt;/code&gt;, binds it to the local name &lt;code&gt;bind&lt;/code&gt;, then does &lt;code&gt;p&lt;/code&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;run env (&lt;span class="dt"&gt;Inp&lt;/span&gt; src bind p) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; &lt;span class="dt"&gt;Wrap&lt;/span&gt; c &lt;span class="fu"&gt;=&lt;/span&gt; env &lt;span class="fu"&gt;M.!&lt;/span&gt; src&lt;br /&gt;  recv &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; readChan c&lt;br /&gt;  _ &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; forkIO &lt;span class="fu"&gt;$&lt;/span&gt; run (M.insert bind recv env) p&lt;br /&gt;  &lt;span class="fu"&gt;return&lt;/span&gt; ()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Why does &lt;code&gt;Inp&lt;/code&gt; invoke &lt;code&gt;forkIO&lt;/code&gt;? It's so that &lt;code&gt;Inp&lt;/code&gt; under &lt;code&gt;Rep&lt;/code&gt; is &lt;em&gt;always&lt;/em&gt; available to receive a message, even if a subprogram is blocking on something else. You can think of this as an identity &lt;code&gt;(Rep x)&lt;/code&gt; ≈ &lt;code&gt;(x :|: Rep x)&lt;/code&gt;. So we fork a new thread for each &amp;quot;connection&amp;quot;, like the UNIX daemons of yore. If we're not under &lt;code&gt;Rep&lt;/code&gt; then this is unnecessary but harmless.&lt;/p&gt;&lt;p&gt;&lt;code&gt;Embed&lt;/code&gt; is something I threw in so that we can observe our program's execution from its side-effects:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;run env (&lt;span class="dt"&gt;Embed&lt;/span&gt; x a) &lt;span class="fu"&gt;=&lt;/span&gt; x &lt;span class="fu"&gt;&amp;gt;&amp;gt;&lt;/span&gt; run env a&lt;/code&gt;&lt;/pre&gt;&lt;p /&gt;&lt;h1 id="compiling-from-the-&amp;#955;-calculus"&gt;Compiling from the λ-calculus&lt;/h1&gt;&lt;p&gt;Sending channels through channels is an interesting model, but how many algorithms can we really implement this way? It turns out that the π-calculus can implement any computable function. We'll demonstrate this by writing a compiler from λ-terms to π-terms.&lt;/p&gt;&lt;p&gt;Here's a simple, untyped lambda calculus with effects:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt; &lt;span class="fu"&gt;:@:&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Eff&lt;/span&gt; (&lt;span class="dt"&gt;IO&lt;/span&gt; ()) &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We'll use a state monad as a source of fresh names. For simplicity, we assume that the input λ-terms do not use any names beginning with &lt;code&gt;'_'&lt;/code&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="kw"&gt;type&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; a &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;State&lt;/span&gt; [&lt;span class="dt"&gt;Name&lt;/span&gt;] a&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;runM &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; a &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; a&lt;br /&gt;runM &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;flip&lt;/span&gt; evalState [&lt;span class="ch"&gt;'_'&lt;/span&gt; &lt;span class="fu"&gt;:&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt; (&lt;span class="ot"&gt;x &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Integer&lt;/span&gt;) &lt;span class="fu"&gt;|&lt;/span&gt; x &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; [&lt;span class="dv"&gt;1&lt;/span&gt;&lt;span class="fu"&gt;..&lt;/span&gt;]]&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;fresh &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt;&lt;br /&gt;fresh &lt;span class="fu"&gt;=&lt;/span&gt; state (\(x&lt;span class="fu"&gt;:&lt;/span&gt;xs) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (x,xs))&lt;br /&gt;&lt;span class="co"&gt;-- With mtl version 1, use 'State' not 'state'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;withFresh &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; (&lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; r) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; r&lt;br /&gt;withFresh f &lt;span class="fu"&gt;=&lt;/span&gt; f &lt;span class="fu"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; fresh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our compiler will produce π-calculus code which needs to send and receive pairs of values. We can encode a pair as a channel with two values enqueued. &lt;code&gt;mkInp2&lt;/code&gt; and &lt;code&gt;mkOut2&lt;/code&gt; construct functions for receiving and sending pairs, respectively.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;mkInp2 &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; (&lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Name&lt;/span&gt;, &lt;span class="dt"&gt;Name&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;)&lt;br /&gt;mkInp2 &lt;span class="fu"&gt;=&lt;/span&gt; withFresh &lt;span class="fu"&gt;$&lt;/span&gt; \pair from (bind1, bind2) p &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Inp&lt;/span&gt; from pair  &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Inp&lt;/span&gt; pair bind1 &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Inp&lt;/span&gt; pair bind2 &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  p&lt;br /&gt;&lt;br /&gt;&lt;span class="ot"&gt;mkOut2 &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; (&lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="dt"&gt;Name&lt;/span&gt;, &lt;span class="dt"&gt;Name&lt;/span&gt;) &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;)&lt;br /&gt;mkOut2 &lt;span class="fu"&gt;=&lt;/span&gt; withFresh &lt;span class="fu"&gt;$&lt;/span&gt; \pair dest (from1, from2) p &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;New&lt;/span&gt; pair       &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Out&lt;/span&gt; pair from1 &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Out&lt;/span&gt; pair from2 &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Out&lt;/span&gt; dest pair  &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  p&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we come to the compiler itself. The π-term produced by &lt;code&gt;compile k e&lt;/code&gt; should evaluate the λ-term &lt;code&gt;e&lt;/code&gt; and send the result to the &amp;quot;continuation channel&amp;quot; named by &lt;code&gt;k&lt;/code&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;compile &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Name&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;M&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;compile k (&lt;span class="dt"&gt;Var&lt;/span&gt; x) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;return&lt;/span&gt; (&lt;span class="dt"&gt;Out&lt;/span&gt; k x &lt;span class="dt"&gt;Nil&lt;/span&gt;)&lt;br /&gt;compile k (&lt;span class="dt"&gt;Eff&lt;/span&gt; eff a) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Embed&lt;/span&gt; eff &lt;span class="fu"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; compile k a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We implement a function as a concurrent process which receives arguments through a channel, and sends back results. (&amp;quot;Lambda as a Service&amp;quot;?) The channel elements are pairs of (function argument, channel where result should be sent).&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;compile k (&lt;span class="dt"&gt;Abs&lt;/span&gt; x b) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  inp2 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; mkInp2&lt;br /&gt;  f    &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; fresh&lt;br /&gt;  ret  &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; fresh&lt;br /&gt;  body &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; compile ret b&lt;br /&gt;  &lt;span class="fu"&gt;return&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;New&lt;/span&gt; f   &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;Out&lt;/span&gt; k f &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;Rep&lt;/span&gt;     &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;      inp2 f (x, ret) body&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the compiler allocates a fresh name for &lt;code&gt;ret&lt;/code&gt; just once, but this name is bound to a different channel by each request.&lt;/p&gt;&lt;p&gt;A function application compiles according to the usual call-by-value rule: evaluate the function, evaluate the argument, then apply. Actually, these steps happen in three concurrent processes, but the &amp;quot;apply&amp;quot; process demands the argument value before sending it to the function, so we end up implementing strict semantics.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;compile k (f &lt;span class="fu"&gt;:@:&lt;/span&gt; x) &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  out2 &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; mkOut2&lt;br /&gt;  [f_cont, f_val, x_cont, x_val] &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; replicateM &lt;span class="dv"&gt;4&lt;/span&gt; fresh&lt;br /&gt;  f_proc &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; compile f_cont f&lt;br /&gt;  x_proc &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; compile x_cont x&lt;br /&gt;  &lt;span class="kw"&gt;let&lt;/span&gt; app_proc&lt;br /&gt;        &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Inp&lt;/span&gt; f_cont f_val &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;          &lt;span class="dt"&gt;Inp&lt;/span&gt; x_cont x_val &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;          out2 f_val (x_val, k) &lt;span class="dt"&gt;Nil&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;return&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;New&lt;/span&gt; f_cont &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    &lt;span class="dt"&gt;New&lt;/span&gt; x_cont &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;    (f_proc &lt;span class="fu"&gt;:|:&lt;/span&gt; x_proc &lt;span class="fu"&gt;:|:&lt;/span&gt; app_proc)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At the top level of a program, we still need a continuation channel. But we'll never read from this channel, because we're only running the program for its effects.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="ot"&gt;lambdaToPi &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Pi&lt;/span&gt;&lt;br /&gt;lambdaToPi b &lt;span class="fu"&gt;=&lt;/span&gt; runM &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="kw"&gt;do&lt;/span&gt;&lt;br /&gt;  k &lt;span class="ot"&gt;&amp;lt;-&lt;/span&gt; fresh&lt;br /&gt;  &lt;span class="dt"&gt;New&lt;/span&gt; k &lt;span class="fu"&gt;&amp;lt;$&amp;gt;&lt;/span&gt; compile k b&lt;/code&gt;&lt;/pre&gt;&lt;p /&gt;&lt;h1 id="testing-the-compiler"&gt;Testing the compiler&lt;/h1&gt;&lt;p&gt;We'll test the compiler by doing some arithmetic on &lt;a href="http://en.wikipedia.org/wiki/Church_encoding#Church_numerals"&gt;Church numerals&lt;/a&gt;.&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span class="co"&gt;-- \m n f -&amp;gt; n (m f)&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;e_mult &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;e_mult &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;n&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  (&lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;n&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;:@:&lt;/span&gt; (&lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;m&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;:@:&lt;/span&gt; &lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;-- \f x -&amp;gt; f (f (f (... x)))&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;e_church &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Int&lt;/span&gt; &lt;span class="ot"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;e_church n &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;.&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="fu"&gt;foldr&lt;/span&gt; (&lt;span class="fu"&gt;:@:&lt;/span&gt;) (&lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;) (&lt;span class="fu"&gt;replicate&lt;/span&gt; n &lt;span class="fu"&gt;$&lt;/span&gt; &lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;f&amp;quot;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;-- \n -&amp;gt; n (\x -&amp;gt; trace &amp;quot;S&amp;quot; x) (trace &amp;quot;0&amp;quot; n)&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;e_shownum &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;e_shownum &lt;span class="fu"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;n&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;$&lt;/span&gt;&lt;br /&gt;  &lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;n&amp;quot;&lt;/span&gt; &lt;span class="fu"&gt;:@:&lt;/span&gt; (&lt;span class="dt"&gt;Abs&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt; (&lt;span class="dt"&gt;Eff&lt;/span&gt; (&lt;span class="fu"&gt;putChar&lt;/span&gt; &lt;span class="ch"&gt;'S'&lt;/span&gt;) (&lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;)))&lt;br /&gt;          &lt;span class="fu"&gt;:@:&lt;/span&gt; (&lt;span class="dt"&gt;Eff&lt;/span&gt; (&lt;span class="fu"&gt;putChar&lt;/span&gt; &lt;span class="ch"&gt;'0'&lt;/span&gt;) (&lt;span class="dt"&gt;Var&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;n&amp;quot;&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;span class="co"&gt;-- compute 2 times 3&lt;/span&gt;&lt;br /&gt;&lt;span class="ot"&gt;e_test &lt;/span&gt;&lt;span class="ot"&gt;::&lt;/span&gt; &lt;span class="dt"&gt;Lam&lt;/span&gt;&lt;br /&gt;e_test &lt;span class="fu"&gt;=&lt;/span&gt; e_shownum &lt;span class="fu"&gt;:@:&lt;/span&gt; (e_mult &lt;span class="fu"&gt;:@:&lt;/span&gt; e_church &lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="fu"&gt;:@:&lt;/span&gt; e_church &lt;span class="dv"&gt;3&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we run it like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GHCi&amp;gt; run M.empty (lambdaToPi e_test)&lt;br /&gt;GHCi&amp;gt; 0SSSSSS&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The answer of 6 is printed to the terminal, asynchronously, in unary.&lt;/p&gt;&lt;h1 id="notes"&gt;Notes&lt;/h1&gt;&lt;p&gt;I thought up this particular scheme for compiling to the π-calculus, but it's probably been documented already.&lt;/p&gt;&lt;p&gt;I'm not sure my π-calculus interpreter is correct. In particular, the term &lt;code&gt;(Rep (x :|: y))&lt;/code&gt; is a &lt;a href="http://en.wikipedia.org/wiki/Fork_bomb"&gt;forkbomb&lt;/a&gt;, when it should be operationally equivalent to &lt;code&gt;(Rep x :|: Rep y)&lt;/code&gt;. I don't know if fixing this would be easy or hard.&lt;/p&gt;&lt;p&gt;Edward Kmett wrote an &lt;a href="http://www.haskell.org/pipermail/haskell-cafe/2010-June/078750.html"&gt;interpreter and pretty-printer&lt;/a&gt; for the π-calculus, in the style of &amp;quot;&lt;a href="http://www.cs.rutgers.edu/~ccshan/tagless/jfp.pdf"&gt;Finally Tagless, Partially Evaluated&lt;/a&gt;&amp;quot; [PDF] by Carette, Kiselyov, and Shan.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-8605777743951714424?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/8605777743951714424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/09/lambda-to-pi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8605777743951714424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/8605777743951714424'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/09/lambda-to-pi.html' title='Lambda to pi'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4796888698241905030</id><published>2011-08-31T23:47:00.000-07:00</published><updated>2011-08-31T23:49:38.735-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='slides'/><category scheme='http://www.blogger.com/atom/ns#' term='markdown'/><category scheme='http://www.blogger.com/atom/ns#' term='pandoc'/><title type='text'>New slides and how I made them</title><content type='html'>&lt;h1 id="new-slides"&gt;New slides&lt;/h1&gt;&lt;p&gt;I've posted PDFs of slides from some talks I gave a while ago.&lt;/p&gt;&lt;p&gt;&lt;a href="http://ugcs.net/~keegan/talks/first-class-concurrency/talk.pdf"&gt;&lt;em&gt;First-Class Concurrency in Haskell&lt;/em&gt;&lt;/a&gt; covers topics in concurrent imperative programming, such as:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;Using closures with concurrency primitives to improve your API&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Using &lt;a href="http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.1.0/Control-Concurrent-MVar.html"&gt;&lt;code&gt;MVar&lt;/code&gt;&lt;/a&gt; to retrieve thread results, as in &lt;a href="http://hackage.haskell.org/package/spawn"&gt;&lt;code&gt;spawn&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;How &lt;a href="http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.1.0/System-Timeout.html"&gt;&lt;code&gt;System.Timeout&lt;/code&gt;&lt;/a&gt; works&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Implementing &lt;a href="http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.1.0/Data-IORef.html"&gt;&lt;code&gt;IORef&lt;/code&gt;&lt;/a&gt; and &lt;a href="http://www.haskell.org/ghc/docs/7.0-latest/html/libraries/base-4.3.1.0/Control-Concurrent-Chan.html"&gt;&lt;code&gt;Chan&lt;/code&gt;&lt;/a&gt; in terms of other primitives&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Implementing the &lt;a href="http://en.wikipedia.org/wiki/Pi_calculus"&gt;π-calculus&lt;/a&gt;, and compiling the &lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;λ-calculus&lt;/a&gt; to it&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This turned out to be far too much material for a one-hour talk, so the slides are probably more valuable than the talk itself. I'm also thinking of expanding the π-calculus bits into a proper blog post at some point.&lt;/p&gt;&lt;p&gt;&lt;a href="http://ugcs.net/~keegan/talks/high-level-ffi/talk.pdf"&gt;&lt;em&gt;High-level FFI in Haskell&lt;/em&gt;&lt;/a&gt; covers tricks for making bindings to C libraries that feel more like native Haskell libraries. Most of the examples are drawn from &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/03/x86-disassembly-in-haskell-with-hdis86.html"&gt;my &lt;code&gt;hdis86&lt;/code&gt; library&lt;/a&gt; . This includes:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;Translating C types to idiomatic Haskell types&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Passing Haskell functions as C function pointers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Passing &lt;a href="http://hackage.haskell.org/package/bytestring"&gt;&lt;code&gt;ByteString&lt;/code&gt;s&lt;/a&gt; as C buffers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Automatic locking and memory management of library state&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Exposing a C library's state machine as a lazy pure function&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Bundling a C library with &lt;a href="http://www.haskell.org/cabal/"&gt;Cabal&lt;/a&gt; while also allowing dynamic linking&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These slides were available before, in a somewhat strange HTML format. The new PDFs are more portable and I think they look nicer, too.&lt;/p&gt;&lt;h1 id="how-i-made-the-slides"&gt;How I made the slides&lt;/h1&gt;&lt;p&gt;I originally wrote the slides in &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; format and converted them to a &lt;a href="http://meyerweb.com/eric/tools/s5/"&gt;S5&lt;/a&gt; slideshow using &lt;a href="http://johnmacfarlane.net/pandoc/"&gt;pandoc&lt;/a&gt;. This was a great way to quickly prepare slides, including syntax-highlighted Haskell code. However I ran into a few limitations:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li&gt;&lt;p&gt;Slide layout depends on window size and screen resolution, rendering my obsessive tweaking useless. In some cases the text would run off the edge of the screen or overlap other elements.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The slides don't work at all in Chromium, as of the S5 version I used initially. I also got reports of issues with other browsers.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I wanted to switch over to &lt;a href="http://en.wikipedia.org/wiki/Beamer_(LaTeX)"&gt;Beamer&lt;/a&gt;, as I'd seen some very high-quality slides produced using that package. This would also provide a PDF that renders exactly the same on every machine. Fortunately, pandoc can output &lt;span class="latex"&gt;L&lt;sup&gt;a&lt;/sup&gt;T&lt;sub&gt;e&lt;/sub&gt;X&lt;/span&gt; code suitable for Beamer. I can keep using the lightweight syntax of Markdown, and most of my old slide source code works as-is. Once again pandoc handles a tricky problem with ease.&lt;/p&gt;&lt;p&gt;I followed &lt;a href="http://www.music.mcgill.ca/~sinclair/content/blog/using_markdown_for_beamer_presentations"&gt;this scheme&lt;/a&gt; with a few modifications. For example, &lt;code&gt;pdflatex&lt;/code&gt; was unhappy with slides (&amp;quot;frames&amp;quot;) containing &lt;code&gt;verbatim&lt;/code&gt; text environments. The solution was to declare all frames as &amp;quot;fragile&amp;quot;, whatever that means:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode LaTeX"&gt;\begin{frame}[fragile]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Recent versions of pandoc accept the &lt;code&gt;--listings&lt;/code&gt; option and will use the &lt;spanclass="latex"&gt;L&lt;sup&gt;a&lt;/sup&gt;T&lt;sub&gt;e&lt;/sub&gt;X&lt;/span&gt; &lt;a href="http://en.wikibooks.org/wiki/LaTeX/Packages/Listings"&gt;&lt;code&gt;listings&lt;/code&gt;&lt;/a&gt; package to render nicely-formatted source code. &lt;a href="http://www.tjansson.dk/?p=419"&gt;This article&lt;/a&gt; was helpful for configuring &lt;code&gt;listings&lt;/code&gt;. The default Haskell style has a rather odd definition of what counts as a keyword, so I wrote a custom language definition. I ended up with this &lt;spanclass="latex"&gt;L&lt;sup&gt;a&lt;/sup&gt;T&lt;sub&gt;e&lt;/sub&gt;X&lt;/span&gt; header, which you can pass to pandoc using &lt;code&gt;-H&lt;/code&gt;:&lt;/p&gt;&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode LaTeX"&gt;\usepackage{listings}&lt;br /&gt;\usepackage{color}&lt;br /&gt;&lt;br /&gt;\lstdefinelanguage{Haskell_mod}{&lt;br /&gt;    otherkeywords={.., ::, |, &amp;lt;-, -&amp;gt;, @, ~, =, =&amp;gt;},&lt;br /&gt;    morekeywords={&lt;br /&gt;       case, class, data, default, deriving, do, else,&lt;br /&gt;       foreign, if, import, in, infix, infixl, infixr,&lt;br /&gt;       instance, let, module, newtype, of, then, type,&lt;br /&gt;       where, _, forall, ccall },&lt;br /&gt;    sensitive,&lt;br /&gt;    morecomment=[l]--,&lt;br /&gt;    morecomment=[n]{\{-}{-\}},&lt;br /&gt;    morestring=[b]&amp;quot;&lt;br /&gt;}[keywords,comments,strings]&lt;br /&gt;&lt;br /&gt;\lstset{&lt;br /&gt;    language=Haskell_mod,&lt;br /&gt;    basicstyle=\ttfamily,&lt;br /&gt;    keywordstyle=\color[rgb]{0,0,1},&lt;br /&gt;    commentstyle=\color[rgb]{0.133,0.545,0.133},&lt;br /&gt;    stringstyle=\color[rgb]{0.627,0.126,0.941},&lt;br /&gt;    showstringspaces=false,&lt;br /&gt;    frame=single&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Markdown sources for the slides are available: &lt;a href="http://ugcs.net/~keegan/talks/first-class-concurrency/talk.text"&gt;1&lt;/a&gt;, &lt;a href="http://ugcs.net/~keegan/talks/high-level-ffi/talk.text"&gt;2&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;My biggest remaining complaint is that I have a lot of explicit spacing commands, e.g. &lt;code&gt;\vspace{1em}&lt;/code&gt;. These are used for logical grouping, and so can't be fully inferred, but maybe there's a better (partial?) solution.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4796888698241905030?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4796888698241905030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/08/new-slides-and-how-i-made-them.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4796888698241905030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4796888698241905030'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/08/new-slides-and-how-i-made-them.html' title='New slides and how I made them'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-6081042704109669426</id><published>2011-03-19T15:43:00.000-07:00</published><updated>2011-03-19T15:43:33.718-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hdis86'/><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>x86 disassembly in Haskell with hdis86</title><content type='html'>&lt;p&gt;The first serious projects I coded in Haskell were compilers, code analyzers, and the like. I think it's a domain that really plays to the strengths of the language. So it makes sense that we'd want a top-notch disassembler library for Haskell.&lt;/p&gt;&lt;p&gt;&lt;a href="http://udis86.sourceforge.net/"  &gt;&lt;code    &gt;udis86&lt;/code    &gt;&lt;/a  &gt; is a fast, complete, flexible disassembler for x86 and x86-64 / AMD64. It provides a clean C API, which was no trouble to &lt;a href="http://book.realworldhaskell.org/read/interfacing-with-c-the-ffi.html"  &gt;import&lt;/a  &gt; using &lt;a href="http://haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html"  &gt;&lt;code    &gt;hsc2hs&lt;/code    &gt;&lt;/a  &gt;. But any C API is going to feel clunky next to high-level idiomatic Haskell code. So I built two additional layers of wrapping, to make something that will feel like a natural part of your next Haskell app.&lt;/p&gt;&lt;p&gt;You can download my library &lt;code  &gt;hdis86&lt;/code  &gt; from &lt;a href="http://hackage.haskell.org/package/hdis86"  &gt;Hackage&lt;/a  &gt;, or browse the source at &lt;a href="https://github.com/kmcallister/hdis86"  &gt;GitHub&lt;/a  &gt;. By default, a copy of &lt;code  &gt;udis86&lt;/code  &gt; is embedded in &lt;code  &gt;hdis86&lt;/code  &gt;. If you already have &lt;code  &gt;udis86&lt;/code  &gt; installed as a shared library, you can link against that instead.&lt;/p&gt;&lt;div id="getting-started"&gt;&lt;h1  &gt;Getting started&lt;/h1  &gt;&lt;p  &gt;Let's try it out. We'll feed in a &lt;a href="http://hackage.haskell.org/package/bytestring"    &gt;&lt;code      &gt;ByteString&lt;/code      &gt;&lt;/a    &gt; of machine code, and pretty-print the result with &lt;a href="http://hackage.haskell.org/package/groom"    &gt;&lt;code      &gt;groom&lt;/code      &gt;&lt;/a    &gt;.&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ ghci&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;:m + Hdis86 Data.ByteString Text.Groom&lt;/span&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;let code = pack [0xcc, 0xf0, 0xff, 0x44, 0x9e, 0x0f]&lt;/span&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;Prelude.putStrLn . groom $ disassemble intel64 code&lt;/span&gt;[Inst [] Iint3 [], Inst [Lock] Iinc   [Mem      (Memory{mSize = Bits32, mBase = Reg64 RSI, mIndex = Reg64 RBX,              mScale = 4, mOffset = Immediate{iSize = Bits8, iValue = 15}})]]&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;If you're not familiar with x86, you might be surprised by the range of simple and complicated instructions. The first instruction is a humble &lt;a href="http://siyobik.info/index.php?module=x86&amp;amp;id=142"    &gt;&lt;code      &gt;int3&lt;/code      &gt;&lt;/a    &gt;, which executes a &lt;a href="http://mainisusuallyafunction.blogspot.com/2011/01/implementing-breakpoints-on-x86-linux.html"    &gt;trap to a debugger&lt;/a    &gt;. It takes no operands and has no prefixes.&lt;/p  &gt;&lt;p  &gt;The second instruction is an &lt;a href="http://siyobik.info/index.php?module=x86&amp;amp;id=140"    &gt;increment&lt;/a    &gt; of a 32-bit memory region, whose address is computed by summing the value in register &lt;code    &gt;RSI&lt;/code    &gt;, the value in register &lt;code    &gt;RBX&lt;/code    &gt; times a scale factor of 4, and a fixed offset of 15. This instruction also has a &lt;a href="http://siyobik.info/index.php?module=x86&amp;amp;id=159"    &gt;lock prefix&lt;/a    &gt;, which changes its concurrency semantics. Some prefixes have a direct meaning like this; others (like &lt;code    &gt;Rex&lt;/code    &gt;) will change how the disassembler decodes operands.&lt;/p  &gt;&lt;p  &gt;We can also ask for Intel-style assembly syntax:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;let cfg = intel64 { cfgSyntax = SyntaxIntel }&lt;/span&gt;&lt;span class="Prompt"&gt;λ&amp;gt;&lt;/span&gt; &lt;span class="Entry"&gt;mapM_ (Prelude.putStrLn . mdAssembly) $ disassembleMetadata cfg code&lt;/span&gt;int3 lock inc dword [rsi+rbx*4+0xf]&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="analyzing-instructions"&gt;&lt;h1  &gt;Analyzing instructions&lt;/h1  &gt;&lt;p  &gt;If we're just printing code, &lt;code    &gt;show&lt;/code    &gt;ing an &lt;code    &gt;Instruction&lt;/code    &gt; is needlessly verbose. The real point of the &lt;code    &gt;Instruction&lt;/code    &gt; type is machine-code analysis, with the help of Haskell's pattern matching capabilities.&lt;/p  &gt;&lt;p  &gt;Sometimes two fragments of code will differ only in which registers they use. Perhaps two compilers made different choices during &lt;a href="http://en.wikipedia.org/wiki/Register_allocation"    &gt;register allocation&lt;/a    &gt;. We'll write a program to detect this.&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Hdis86&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Text.Groom&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Control.Monad&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; M&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.ByteString&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; B&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;When one code fragment uses register X the same way that another fragment uses register Y, we record a constraint &lt;code    &gt;X :-&amp;gt; Y&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Constraint = Register :-&amp;gt; Register&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We compare the two code fragments to produce a list of &lt;code    &gt;Constraint&lt;/code    &gt;s, or &lt;code    &gt;Nothing&lt;/code    &gt; if they differ in ways beyond register selection. We'll use this helper function to check a list of Boolean conditions:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;(==&amp;gt;) :: [&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Bool&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;] -&amp;gt; a -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Maybe&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;ps ==&amp;gt; x = guard (&lt;/span      &gt;&lt;span class="Function"      &gt;and&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ps) &amp;gt;&amp;gt; &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We compare operands pairwise. Register operands are easy:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;operand ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Operand -&amp;gt; Operand -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Maybe&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [Constraint]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;operand (Reg rx) (Reg ry) = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [rx :-&amp;gt; ry]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;For a memory operand, we need to check that the size, scale, and offset are equal:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- size, base register, index register, scale, offset&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;operand (Mem (Memory sx bx ix kx ox)) (Mem (Memory sy by iy ky oy))&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  = [sx == sy, kx == ky, ox == oy] ==&amp;gt; [bx :-&amp;gt; by, ix :-&amp;gt; iy]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Immediate operands need a similar check for equality, but they don't produce any register constraints:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;operand (Ptr   px) (Ptr   py) = [px == py] ==&amp;gt; []&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;operand (Imm   ix) (Imm   iy) = [ix == ix] ==&amp;gt; []&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;operand (Jump  ix) (Jump  iy) = [ix == iy] ==&amp;gt; []&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;operand (Const ix) (Const iy) = [ix == iy] ==&amp;gt; []&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;In all other cases, we have two different operand constructors, which means they don't match:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;operand _ _ = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Nothing&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;To check a pair of instructions, we check their prefixes and opcodes, then check operands pairwise:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;inst ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Instruction -&amp;gt; Instruction -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Maybe&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [Constraint]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;inst (Inst px ox rx) (Inst py oy ry) = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  guard $ &lt;/span      &gt;&lt;span class="Function"      &gt;and&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [px == py, ox == oy, &lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; rx == &lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ry]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;concat&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Others InfixOperator"      &gt;`fmap`&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; zipWithM operand rx ry&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Once we have a list of &lt;code    &gt;Constraint&lt;/code    &gt;s, we need to check it for consistency. If register X maps to Y in one place, it can't map to Z somewhere else:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;unify ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [Constraint] -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Maybe&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;M.Map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Register Register)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;unify = foldM f M.empty &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f m (rx :-&amp;gt; ry) = &lt;/span      &gt;&lt;span class="Keyword"      &gt;case&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; M.&lt;/span      &gt;&lt;span class="Function"      &gt;lookup&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; rx m &lt;/span      &gt;&lt;span class="Keyword"      &gt;of&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Nothing&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  -&amp;gt; &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (M.insert rx ry m)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ry' -&amp;gt; [ry == ry'] ==&amp;gt; m&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Now we put it all together, checking consistency in both directions:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;regMap ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [Instruction] -&amp;gt; [Instruction] -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Maybe&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;M.Map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Register Register)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;regMap xs ys = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  cs &amp;lt;- &lt;/span      &gt;&lt;span class="Function"      &gt;concat&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Others InfixOperator"      &gt;`fmap`&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; zipWithM inst xs ys&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; swap (x :-&amp;gt; y) = (y :-&amp;gt; x)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  _ &amp;lt;- unify $ &lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; swap cs&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  unify cs&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;main ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ()&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;main = &lt;/span      &gt;&lt;span class="Function"      &gt;putStrLn&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; . groom $ regMap (f prog_a) (f prog_b) &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f = disassemble intel64&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We'll test these two code fragments:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;prog_a, &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;prog_b ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;B.ByteString&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;prog_a = B.pack&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  [ &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x7e&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x3a&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;               &lt;/span      &gt;&lt;span class="Comment"      &gt;-- jle  0x3c&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x48&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x89&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0xf5&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  rbp, rsi&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0xbb&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  ebx, 0x1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x48&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x8b&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x7d&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x08&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ] &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  rdi, [rbp+0x8]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;prog_b = B.pack&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  [ &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x7e&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x3a&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;               &lt;/span      &gt;&lt;span class="Comment"      &gt;-- jle  0x3c&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x48&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x89&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0xf3&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  rbx, rsi&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0xbd&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  ebp, 0x1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  , &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x48&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x8b&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x7b&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x08&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ] &lt;/span      &gt;&lt;span class="Comment"      &gt;-- mov  rdi, [rbx+0x8]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;And the result is:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ runhaskell regmap.hs Just  (fromList     [(RegNone, RegNone), (Reg32 RBX, Reg32 RBP),      (Reg64 RBP, Reg64 RBX), (Reg64 RSI, Reg64 RSI),      (Reg64 RDI, Reg64 RDI)])&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;In reality, this analysis is grossly incomplete. Some instructions have implicit register operands, and some pairs of registers overlap, like &lt;code    &gt;EBX&lt;/code    &gt; and &lt;code    &gt;RBX&lt;/code    &gt;. And we have to understand contextual requirements. It's not okay to remap &lt;code    &gt;RAX&lt;/code    &gt; to &lt;code    &gt;RBX&lt;/code    &gt; if some calling code is expecting a return value in &lt;code    &gt;RAX&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;The complexity of x86 (not to mention the halting problem) means that binary code analysis will never be easy. Hopefully &lt;code    &gt;hdis86&lt;/code    &gt; can be one of many useful tools in this domain. As always, suggestions or patches are welcome.&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-6081042704109669426?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/6081042704109669426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/03/x86-disassembly-in-haskell-with-hdis86.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6081042704109669426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/6081042704109669426'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/03/x86-disassembly-in-haskell-with-hdis86.html' title='x86 disassembly in Haskell with hdis86'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4814486916519653280</id><published>2011-01-09T13:57:00.000-08:00</published><updated>2011-01-09T17:57:20.665-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='breakfast'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Implementing breakpoints on x86 Linux</title><content type='html'>&lt;p&gt;Debugger features such as &lt;a href="http://www.ofb.net/gnu/gdb/gdb_28.html"  &gt;breakpoints&lt;/a  &gt; go well beyond the normal ways in which programs interact. How can one process force another process to pause at a particular line of code? We can bet that the debugger is using some special features of the CPU and/or operating system.&lt;/p&gt;&lt;p&gt;As I learned about implementing breakpoints, I was surprised to find that these interfaces, while arcane, are not actually very complex. In this article we'll implement a minimal but working breakpoints library in about 75 lines of C code. All of the code is shown here, and is also available on &lt;a href="https://github.com/kmcallister/breakfast"  &gt;GitHub&lt;/a  &gt;.&lt;/p&gt;&lt;p&gt;True, most of us will never write a debugger. But breakpoints are useful in many other tools: profilers, compatibility layers, security scanners, etc. If your program has to interact deeply with another process, without modifying its source code, breakpoints might just do the trick. And I think there's value in knowing what your debugger is &lt;em  &gt;really&lt;/em  &gt; doing.&lt;/p&gt;&lt;p&gt;Our code will compile with &lt;a href="http://gcc.gnu.org/"  &gt;gcc&lt;/a  &gt; and will run on &lt;a href="http://kernel.org/"  &gt;Linux&lt;/a  &gt; machines with 32- or 64-bit &lt;a href="http://en.wikipedia.org/wiki/X86"  &gt;x86 processors&lt;/a  &gt;. I'll assume you're familiar with the basics of UNIX programming in C. We'll make heavy use of the &lt;code  &gt;ptrace&lt;/code  &gt; system call, which I'll try to explain as we go. If you're looking for other reading about &lt;code  &gt;ptrace&lt;/code  &gt;, I highly recommend &lt;a href="http://blog.nelhage.com/2010/08/write-yourself-an-strace-in-70-lines-of-code/"  &gt;this article&lt;/a  &gt; and of course the &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/ptrace.2.html"  &gt;manpage&lt;/a  &gt;.&lt;/p&gt;&lt;div id="the-api"&gt;&lt;h1  &gt;The API&lt;/h1  &gt;&lt;p  &gt;Our little breakpoint library is named &lt;code    &gt;breakfast&lt;/code    &gt;. Here's &lt;code    &gt;breakfast.h&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Others Preprocessor"      &gt;#ifndef _BREAKFAST_H&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define _BREAKFAST_H&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/types.h&amp;gt;&lt;/span      &gt;&lt;span class="Others Preprocessor"      &gt;  &lt;/span      &gt;&lt;span class="Comment"      &gt;/* for pid_t */&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;typedef&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;target_addr_t&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_attach&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;target_addr_t breakfast_getip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;breakfast_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; target_addr_t addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#endif&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Before we dive into the implementation, we'll describe the API our library provides. &lt;code    &gt;breakfast&lt;/code    &gt; is used by one process (the &lt;em    &gt;tracing process&lt;/em    &gt;) to place breakpoints inside the code of another process (the &lt;em    &gt;target process&lt;/em    &gt;). To establish this relationship, the tracing process calls &lt;code    &gt;breakfast_attach&lt;/code    &gt; with the target's process ID. This also suspends execution of the target.&lt;/p  &gt;&lt;p  &gt;We use &lt;code    &gt;breakfast_getip&lt;/code    &gt; to read the target's &lt;em    &gt;instruction pointer&lt;/em    &gt;, which holds the address of the next instruction it will execute. Note that this is a pointer to machine code within the &lt;em    &gt;target&lt;/em    &gt;'s address space. Dereferencing the pointer within our tracing process would make little sense. The type alias &lt;code    &gt;target_addr_t&lt;/code    &gt; reminds us of this fact.&lt;/p  &gt;&lt;p  &gt;We use &lt;code    &gt;breakfast_break&lt;/code    &gt; to create a breakpoint at a specified address in the target's machine code. This function returns a pointer to a &lt;code    &gt;breakpoint&lt;/code    &gt; structure, which has unspecified contents.&lt;/p  &gt;&lt;p  &gt;Calling &lt;code    &gt;breakfast_run&lt;/code    &gt; lets the target run until it hits a breakpoint or it exits; &lt;code    &gt;breakfast_run&lt;/code    &gt; returns &lt;code    &gt;1&lt;/code    &gt; or &lt;code    &gt;0&lt;/code    &gt; respectively. On the first invocation, we'll pass &lt;code    &gt;NULL&lt;/code    &gt; for the argument &lt;code    &gt;bp&lt;/code    &gt;. On subsequent calls, we're resuming from a breakpoint, and we must pass the corresponding &lt;code    &gt;breakpoint&lt;/code    &gt; struct pointer. The &lt;code    &gt;breakfast_getip&lt;/code    &gt; function will tell us the breakpoint's address, but it's our responsibility to map this to the correct &lt;code    &gt;breakpoint&lt;/code    &gt; structure.&lt;/p  &gt;&lt;/div&gt;&lt;div id="the-trap-instruction"&gt;&lt;h1  &gt;The trap instruction&lt;/h1  &gt;&lt;p  &gt;We will implement a breakpoint by inserting a new CPU instruction into the target's memory at the breakpoint address. This instruction should suspend execution of the target and give control back to the OS.&lt;/p  &gt;&lt;p  &gt;There are many ways to return control to the OS, but we'd like to minimize disruption to the code we're hot-patching. x86 provides an instruction for exactly this purpose. It's named &lt;code    &gt;int3&lt;/code    &gt; and is encoded as the single byte &lt;code    &gt;0xCC&lt;/code    &gt;. When the CPU executes &lt;code    &gt;int3&lt;/code    &gt;, it will stop what it's doing and jump to the interrupt 3 service routine, which is a piece of code chosen by the OS. On Linux, this routine will send the signal &lt;code    &gt;SIGTRAP&lt;/code    &gt; to the current process.&lt;/p  &gt;&lt;p  &gt;Since we're placing &lt;code    &gt;int3&lt;/code    &gt; in the target's code, the target will receive a &lt;code    &gt;SIGTRAP&lt;/code    &gt;. Under normal circumstances this would invoke the target's &lt;code    &gt;SIGTRAP&lt;/code    &gt; handler, which usually kills the process. Instead we'd like the tracing process to intercept this signal and interpret it as the target hitting a breakpoint. We'll accomplish this through the magic of &lt;code    &gt;ptrace&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;Let's start off &lt;code    &gt;breakfast.c&lt;/code    &gt; with some includes:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/ptrace.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/reg.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/wait.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;stdlib.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;quot;breakfast.h&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Then we'll define our trap instruction:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Others Preprocessor"      &gt;#if defined(__i386)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define REGISTER_IP EIP&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_LEN    1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_INST   0xCC&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_MASK   0xFFFFFF00&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#elif defined(__x86_64)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define REGISTER_IP RIP&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_LEN    1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_INST   0xCC&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#define TRAP_MASK   0xFFFFFFFFFFFFFF00&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#else&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#error Unsupported architecture&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#endif&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We use some GCC pre-defined macros to discover the machine architecture, and we define a few constants accordingly. &lt;code    &gt;REGISTER_IP&lt;/code    &gt; expands to a constant from &lt;code    &gt;sys/reg.h&lt;/code    &gt; which identifies the machine register holding the instruction pointer.&lt;/p  &gt;&lt;p  &gt;The trap instruction is stored as an integer &lt;code    &gt;TRAP_INST&lt;/code    &gt; and its length in bytes is &lt;code    &gt;TRAP_LEN&lt;/code    &gt;. These are the same on 32- and 64-bit x86. The trap instruction is a single byte, but we'll read and write the target's memory in increments of one machine word, meaning 32 or 64 bits. So we'll read 4 or 8 bytes of machine code, clear out the first byte with &lt;code    &gt;TRAP_MASK&lt;/code    &gt;, and substitute &lt;code    &gt;0xCC&lt;/code    &gt;. Since x86 is a &lt;a href="http://en.wikipedia.org/wiki/Endianness"    &gt;little-endian&lt;/a    &gt; architecture, the first byte in memory is the least-significant byte of an integer machine word.&lt;/p  &gt;&lt;/div&gt;&lt;div id="invoking-ptrace"&gt;&lt;h1  &gt;Invoking &lt;code    &gt;ptrace&lt;/code    &gt;&lt;/h1  &gt;&lt;p  &gt;All of the various &lt;code    &gt;ptrace&lt;/code    &gt; requests are made through a single system call named &lt;code    &gt;ptrace&lt;/code    &gt;. The first argument specifies the type of request and the meaning of any remaining arguments. The second argument is almost always the process ID of the target.&lt;/p  &gt;&lt;p  &gt;Before we can mess with the target process, we need to attach to it:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_attach&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_ATTACH&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  waitpid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;amp;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_SETOPTIONS&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PTRACE_O_TRACEEXIT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The &lt;code    &gt;PTRACE_ATTACH&lt;/code    &gt; request will stop the target with &lt;code    &gt;SIGSTOP&lt;/code    &gt;. We wait for the target to receive this signal. We also request to receive a notification when the target exits, which I'll explain below.&lt;/p  &gt;&lt;p  &gt;Note that &lt;code    &gt;ptrace&lt;/code    &gt; and &lt;code    &gt;waitpid&lt;/code    &gt; could fail in various ways. In a real application you'd want to check the return value and/or &lt;code    &gt;errno&lt;/code    &gt;. For brevity I've omitted those checks in this article.&lt;/p  &gt;&lt;p  &gt;We use another &lt;code    &gt;ptrace&lt;/code    &gt; request to get the value of the target's instruction pointer:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;target_addr_t breakfast_getip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; v &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_PEEKUSER&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;sizeof&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;REGISTER_IP&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;target_addr_t&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;v &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; TRAP_LEN&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Since the target process is suspended, it's not running on any CPU, and its instruction pointer is not stored in a real CPU register. Instead, it's saved to a &amp;quot;user area&amp;quot; in kernel memory. We use the &lt;code    &gt;PTRACE_PEEKUSER&lt;/code    &gt; request to read a machine word from this area at a specified byte offset. The constants in &lt;code    &gt;sys/regs.h&lt;/code    &gt; give the order in which registers appear, so we simply multiply by &lt;code    &gt;sizeof(long)&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;After we hit a breakpoint, the saved IP points to the instruction &lt;em    &gt;after&lt;/em    &gt; the trap instruction. When we resume execution, we'll go back and execute the original instruction that we overwrote with the trap. So we subtract &lt;code    &gt;TRAP_LEN&lt;/code    &gt; to give the true address of the next instruction.&lt;/p  &gt;&lt;/div&gt;&lt;div id="creating-breakpoints"&gt;&lt;h1  &gt;Creating breakpoints&lt;/h1  &gt;&lt;p  &gt;We need to remember two things about a breakpoint: the address of the code we replaced, and the code which originally lived there.&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  target_addr_t addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; orig_code&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;};&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;To enable a breakpoint, we save the original code and insert our trap instruction:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;static&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; enable&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; orig &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_PEEKTEXT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_POKETEXT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;orig &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;amp;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; TRAP_MASK&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;|&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; TRAP_INST&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;orig_code &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; orig&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The &lt;code    &gt;PTRACE_PEEKTEXT&lt;/code    &gt; request reads a machine word from the target's code address space, which is named &amp;quot;text&amp;quot; for historical reasons. &lt;code    &gt;PTRACE_POKETEXT&lt;/code    &gt; writes to that space. On x86 Linux there's actually no difference between code and data spaces, so &lt;code    &gt;PTRACE_PEEKDATA&lt;/code    &gt; and &lt;code    &gt;PTRACE_POKEDATA&lt;/code    &gt; would work just as well.&lt;/p  &gt;&lt;p  &gt;Creating a breakpoint is straightforward:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;breakfast_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; target_addr_t addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; malloc&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Keyword"      &gt;sizeof&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;));&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;addr &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  enable&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;To disable a breakpoint we just write back the saved word:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;static&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; disable&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_POKETEXT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;orig_code&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="running-and-stepping"&gt;&lt;h1  &gt;Running and stepping&lt;/h1  &gt;&lt;p  &gt;Once we attach to the target, its execution stops. Here's how to resume it:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;static&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; cmd&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Comment"      &gt;/* defined momentarily */&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_POKEUSER&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;sizeof&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;REGISTER_IP&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;-&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;addr&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    disable&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(!&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PTRACE_SINGLESTEP&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;))&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    enable&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; bp&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PTRACE_CONT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We ask &lt;code    &gt;ptrace&lt;/code    &gt; to continue execution — but if we're resuming from a breakpoint, we have to do some cleanup first. We rewind the instruction pointer so that the next instruction to execute is at the breakpoint. Then we disable the breakpoint and make the target execute just one instruction. Once we're past the breakpoint, we can re-enable it for next time. &lt;code    &gt;run&lt;/code    &gt; returns &lt;code    &gt;0&lt;/code    &gt; if the target exits, which theoretically could happen during our single-step.&lt;/p  &gt;&lt;p  &gt;The last piece of the puzzle is &lt;code    &gt;run&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;static&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; cmd&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; last_sig &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; event&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;while&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;cmd&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; last_sig&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    waitpid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;amp;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;WIFEXITED&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;))&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;WIFSTOPPED&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;))&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      last_sig &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; WSTOPSIG&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;last_sig &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;==&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; SIGTRAP&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;        event &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;status &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;gt;&amp;gt;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;16&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;amp;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="BaseN Hex"      &gt;0xffff&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;        &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;event &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;==&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PTRACE_EVENT_EXIT&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;?&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;:&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;&lt;code    &gt;cmd&lt;/code    &gt; is either &lt;code    &gt;PTRACE_CONT&lt;/code    &gt; or &lt;code    &gt;PTRACE_SINGLESTEP&lt;/code    &gt;. In the latter case, the OS will set a control bit to make the CPU raise interrupt 3 after one instruction has completed.&lt;/p  &gt;&lt;p  &gt;&lt;code    &gt;ptrace&lt;/code    &gt; will let the target run until it exits or receives a signal. We use the &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/wait.2.html"    &gt;&lt;code      &gt;wait&lt;/code      &gt; macros&lt;/a    &gt; to see what happened. If the target exited, we simply return &lt;code    &gt;0&lt;/code    &gt;. If it received a signal, we check which one. Anything other than &lt;code    &gt;SIGTRAP&lt;/code    &gt; should be delivered through to the target, which we accomplish by passing the signal number to the next &lt;code    &gt;ptrace&lt;/code    &gt; call.&lt;/p  &gt;&lt;p  &gt;In the case of &lt;code    &gt;SIGTRAP&lt;/code    &gt;, we check bits 16-31 of &lt;code    &gt;status&lt;/code    &gt; for the value &lt;code    &gt;PTRACE_EVENT_EXIT&lt;/code    &gt;, which indicates that the target is about to exit. Recall that we requested this notification by setting the option &lt;code    &gt;PTRACE_O_TRACEEXIT&lt;/code    &gt;. You'd think (at least, I did) that checking &lt;code    &gt;WIFEXITED&lt;/code    &gt; should be enough. But I ran into a problem where delivering a fatal signal to the target would make the tracing process loop forever. I fixed it by adding this extra check. I'm certainly no &lt;code    &gt;ptrace&lt;/code    &gt; expert and I'd be interested to hear more about what's going on here.&lt;/p  &gt;&lt;/div&gt;&lt;div id="testing-it"&gt;&lt;h1  &gt;Testing it&lt;/h1  &gt;&lt;p  &gt;That's all for &lt;code    &gt;breakfast.c&lt;/code    &gt;! Now let's write a small &lt;code    &gt;test.c&lt;/code    &gt;.&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/types.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;signal.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;unistd.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;stdio.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;quot;breakfast.h&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; child&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;();&lt;/span      &gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; parent&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; main&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;()&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;((&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fork&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;())&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;==&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    child&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;();&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;else&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    parent&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We fork two separate processes, a parent and a child. The child will do some computation we hope to observe. Let's make it compute the famous &lt;a href="http://en.wikipedia.org/wiki/Factorial"    &gt;factorial function&lt;/a    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; n&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;n &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;&amp;lt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; n &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;n&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;-1&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; child&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;()&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  kill&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;getpid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(),&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; SIGSTOP&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  printf&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;fact(5) = %d&lt;/span      &gt;&lt;span class="Char StringChar"      &gt;\n&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;5&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;));&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The parent is going to invoke &lt;code    &gt;PTRACE_ATTACH&lt;/code    &gt; and send the child &lt;code    &gt;SIGSTOP&lt;/code    &gt;, but the child might finish executing before the parent gets a chance to call &lt;code    &gt;ptrace&lt;/code    &gt;. So we make the child preemptively stop itself. This isn't a problem when attaching to a long-running process.&lt;/p  &gt;&lt;p  &gt;Actually, for this fork-and-trace-child pattern, we should be using &lt;code    &gt;PTRACE_TRACEME&lt;/code    &gt;. But we implemented a minimal library, so we work with what we have.&lt;/p  &gt;&lt;p  &gt;The parent uses &lt;code    &gt;breakfast&lt;/code    &gt; to place breakpoints in the child:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; parent&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid_t pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;struct&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakpoint &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;fact_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;last_break &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; NULL&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;void&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;fact_ip &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;last_ip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  breakfast_attach&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  fact_break &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact_ip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;while&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;breakfast_run&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; last_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;))&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    last_ip &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; breakfast_getip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;last_ip &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;==&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact_ip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      printf&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Break at fact()&lt;/span      &gt;&lt;span class="Char StringChar"      &gt;\n&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      last_break &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact_break&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;else&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      printf&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Unknown trap at %p&lt;/span      &gt;&lt;span class="Char StringChar"      &gt;\n&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; last_ip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      last_break &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; NULL&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;In principle we can use &lt;code    &gt;breakfast&lt;/code    &gt; to trace any running process we own, even if we don't have its source code. But we still need a way to find interesting breakpoint addresses. Here it's as easy as we could want: the child forked from our process, so we get the address of its &lt;code    &gt;fact&lt;/code    &gt; function just by taking the address of our &lt;code    &gt;fact&lt;/code    &gt; function.&lt;/p  &gt;&lt;p  &gt;Let's try it out:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ gcc -Wall -o test test.c breakfast.c$ ./testBreak at fact()Break at fact()Break at fact()Break at fact()Break at fact()fact(5) = 120&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We can see the five calls to &lt;code    &gt;fact&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="inspecting-the-target"&gt;&lt;h1  &gt;Inspecting the target&lt;/h1  &gt;&lt;p  &gt;The ability to count function calls is already useful for performance profiling. But we'll usually want to get more information out of the stopped target. Let's see if we can read the arguments passed to &lt;code    &gt;fact&lt;/code    &gt;. This part will be specific to 64-bit x86, though the idea generalizes.&lt;/p  &gt;&lt;p  &gt;Each architecture defines a C calling convention, which specifies how function arguments are passed, often using a combination of registers and stack slots. On &lt;a href="http://en.wikipedia.org/wiki/X86_calling_conventions#AMD64_ABI_convention"    &gt;64-bit x86&lt;/a    &gt;, the first argument is passed in the &lt;code    &gt;RDI&lt;/code    &gt; register. You can verify this by running &lt;code    &gt;objdump -d test&lt;/code    &gt; and looking at the disassembled code for &lt;code    &gt;fact&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;So we'll modify &lt;code    &gt;test.c&lt;/code    &gt; to read this register:&lt;/p  &gt;&lt;pre class="sourceCode c"  &gt;&lt;code    &gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/ptrace.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Others Preprocessor"      &gt;#include &lt;/span      &gt;&lt;span class="Others Prep.Lib"      &gt;&amp;lt;sys/reg.h&amp;gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Error"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    &lt;/span      &gt;&lt;span class="Keyword"      &gt;if&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;last_ip &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;==&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; fact_ip&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;{&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="DataType DataType"      &gt;int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; arg &lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;=&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ptrace&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;PTRACE_PEEKUSER&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; pid&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;sizeof&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="DataType DataType"      &gt;long&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;)*&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;RDI&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      printf&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;(&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Break at fact(%d)&lt;/span      &gt;&lt;span class="Char StringChar"      &gt;\n&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;,&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; arg&lt;/span      &gt;&lt;span class="Normal Symbol"      &gt;);&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal Symbol"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;And we get:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ gcc -Wall -o test test.c breakfast.c$ ./testBreak at fact(5)Break at fact(4)Break at fact(3)Break at fact(2)Break at fact(1)fact(5) = 120&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Cool!&lt;/p  &gt;&lt;/div&gt;&lt;div id="notes"&gt;&lt;h1  &gt;Notes&lt;/h1  &gt;&lt;p  &gt;This is my first non-trivial project using &lt;code    &gt;ptrace&lt;/code    &gt;, and it's likely I got some details wrong. Please reply with corrections or advice and I'll update the code if necessary.&lt;/p  &gt;&lt;p  &gt;This code is available for &lt;a href="https://github.com/kmcallister/breakfast"    &gt;download&lt;/a    &gt; at GitHub. It's released under a &lt;a href="https://github.com/kmcallister/breakfast/blob/master/LICENSE"    &gt;BSD license&lt;/a    &gt;, which imposes few restrictions. It's definitely not suitable as-is for production use, but feel free to take the code and build something more with it.&lt;/p  &gt;&lt;p  &gt;The x86 architecture has &lt;a href="http://en.wikipedia.org/wiki/X86_debug_register"    &gt;dedicated registers&lt;/a    &gt; for setting breakpoints, subject to various limitations. We ignored this feature in favor of the more flexible software breakpoints. Hardware breakpoints can do some things this technique can't, such as breaking on reads from a particular memory address.&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4814486916519653280?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4814486916519653280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/01/implementing-breakpoints-on-x86-linux.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4814486916519653280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4814486916519653280'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2011/01/implementing-breakpoints-on-x86-linux.html' title='Implementing breakpoints on x86 Linux'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-3677942817296436337</id><published>2010-12-04T19:14:00.000-08:00</published><updated>2010-12-04T19:14:29.954-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Type-level Fix and generic folds</title><content type='html'>&lt;p&gt;This article describes a fixpoint combinator for Haskell types, with some justification of why such a thing would be useful. It's meant to be an accessible introduction to material which is already covered &lt;a href="http://knol.google.com/k/catamorphisms"  &gt;elsewhere&lt;/a  &gt;.&lt;/p&gt;&lt;p&gt;You'll need some basic Haskell knowledge, such as how to define and use polymorphic data types. And you might want to first study the value-level &lt;code  &gt;fix&lt;/code  &gt; function. An excellent introduction can be found &lt;a href="http://www.vex.net/~trebla/haskell/fix.xhtml"  &gt;here&lt;/a  &gt;.&lt;/p&gt;&lt;p&gt;This code is standard Haskell 98, except in the &amp;quot;GHC tricks&amp;quot; section.&lt;/p&gt;&lt;div id="recursive-types"&gt;&lt;h1  &gt;Recursive types&lt;/h1  &gt;&lt;p  &gt;Many useful data types are recursive:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = Zero | Succ Natural     &lt;/span      &gt;&lt;span class="Comment"      &gt;-- natural numbers&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; List a  = Nil  | Cons a (List a)  &lt;/span      &gt;&lt;span class="Comment"      &gt;-- lists&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Tree a  = Node a [Tree a]         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- rose trees&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;In each case, the type declared on the left-hand side of &amp;quot;&lt;code    &gt;=&lt;/code    &gt;&amp;quot; is mentioned on the right-hand side. This is fine, but just for fun let's see if there's another way.&lt;/p  &gt;&lt;p  &gt;We can imagine a language with a keyword &amp;quot;&lt;code    &gt;self&lt;/code    &gt;&amp;quot;, which refers to the type being defined:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = Zero | Succ &lt;span class="Keyword"&gt;self&lt;/span&gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; List a  = Nil  | Cons a &lt;span class="Keyword"&gt;self&lt;/span&gt;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Tree a  = Node a [&lt;span class="Keyword"&gt;self&lt;/span&gt;]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Haskell doesn't have this keyword, so we'll make &lt;code    &gt;self&lt;/code    &gt; into a type parameter:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; NaturalF self = Zero | Succ self&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ListF a  self = Nil  | Cons a self&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; TreeF a  self = Node a [self]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We've changed the names because these aren't the types we wanted. They're non-recursive and each has an extra parameter.&lt;/p  &gt;&lt;p  &gt;To build the recursive type &lt;code    &gt;Natural&lt;/code    &gt; using the non-recursive &lt;code    &gt;NaturalF&lt;/code    &gt;, we need to &amp;quot;tie the knot&amp;quot;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = NaturalF (NaturalF (NaturalF (NaturalF ...)))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;i.e.&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = NaturalF Natural&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;But this is disallowed:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;foo.hs:3:0:    Cycle in type synonym declarations:      foo.hs:3:0-30: type Natural = NaturalF Natural&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Since &lt;code    &gt;type&lt;/code    &gt; defines a transparent synonym, this would generate an infinitely-large type-expression. Haskell disallows those. We need to hide the recursion behind a data constructor:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&lt;span class="Keyword"&gt;newtype&lt;/span&gt; Natural = MkNat (NaturalF Natural)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;When we use this type, the &amp;quot;wrapper&amp;quot; constructor &lt;code    &gt;MkNat&lt;/code    &gt; alternates with the constructors of &lt;code    &gt;NaturalF&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;toNatural ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Integer&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; Natural&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;toNatural &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; = MkNat Zero&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;toNatural n = MkNat . Succ $ toNatural (n&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;-1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="type-level-fix"&gt;&lt;h1  &gt;Type-level &lt;code    &gt;Fix&lt;/code    &gt;&lt;/h1  &gt;&lt;p  &gt;So far this is just pointless complexity. We've replaced one type:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = Zero | Succ Natural&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;with two types:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;    NaturalF self = Zero | Succ self&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;&lt;span class="Keyword"&gt;newtype&lt;/span&gt; Natural       = MkNat (NaturalF Natural)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Notice that the definition of &lt;code    &gt;Natural&lt;/code    &gt; doesn't depend on the structure of natural numbers. Let's rename &lt;code    &gt;Natural&lt;/code    &gt; to &lt;code    &gt;Fix&lt;/code    &gt; and &lt;code    &gt;MkNat&lt;/code    &gt; to &lt;code    &gt;In&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&lt;span class="Keyword"&gt;newtype&lt;/span&gt; Fix   = In (NaturalF Fix)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Then we'll abstract out &lt;code    &gt;NaturalF&lt;/code    &gt; as a type parameter &lt;code    &gt;f&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&lt;span class="Keyword"&gt;newtype&lt;/span&gt; Fix f = In (f (Fix f))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Now &lt;code    &gt;Natural&lt;/code    &gt; is just a synonym:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = Fix NaturalF&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;When we create values of type &lt;code    &gt;Natural&lt;/code    &gt;, we still have &amp;quot;wrapper&amp;quot; constructors:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;toNatural ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Integer&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; Natural&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;toNatural &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; = In Zero&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;toNatural n = In . Succ $ toNatural (n&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;-1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="properties-of-fix"&gt;&lt;h1  &gt;Properties of &lt;code    &gt;Fix&lt;/code    &gt;&lt;/h1  &gt;&lt;p  &gt;Recall that the value-level &lt;code    &gt;fix&lt;/code    &gt; function can be defined as&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;fix f = f (fix f)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This looks a lot like our type&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&lt;span class="Keyword"&gt;newtype&lt;/span&gt; Fix f = In (f (Fix f))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The similarity is reflected at the type and &lt;a href="http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-640004.1.1"    &gt;kind&lt;/a    &gt; levels:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;GHCi&amp;gt; :t fixfix :: (a -&amp;gt; a) -&amp;gt; aGHCi&amp;gt; :k FixFix :: (* -&amp;gt; *) -&amp;gt; *&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;&lt;code    &gt;fix&lt;/code    &gt; is a function which takes another function. &lt;code    &gt;Fix&lt;/code    &gt; is a type constructor which takes another type constructor.&lt;/p  &gt;&lt;p  &gt;The types &lt;code    &gt;Fix f&lt;/code    &gt; and &lt;code    &gt;f (Fix f)&lt;/code    &gt; are isomorphic, and we'll want to convert between them. In one direction we'll use the data constructor&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;I&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;n ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f (Fix f) -&amp;gt; Fix f&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;and the other direction is easily defined as&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;out ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Fix f -&amp;gt; f (Fix f)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;out (In x) = x&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="folding-lists"&gt;&lt;h1  &gt;Folding lists&lt;/h1  &gt;&lt;p  &gt;So why bother writing types this way? Well, we usually don't. But factoring the recursion out of our data type enables us to factor the recursion out of our functions.&lt;/p  &gt;&lt;p  &gt;Consider taking the sum of a list:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;sumF ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Num&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) =&amp;gt; List a -&amp;gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;sumF (In Nil)         = &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;sumF (In (Cons x xs)) = x + sumF xs&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We traverse the structure with the combining function &lt;code    &gt;(+)&lt;/code    &gt;, making a recursive call at each recursive position of the data type. How can we capture this pattern?&lt;/p  &gt;&lt;p  &gt;If we're reducing a value of type &lt;code    &gt;List T&lt;/code    &gt; to get a result of type &lt;code    &gt;R&lt;/code    &gt;, then a value of type &lt;code    &gt;ListF T R&lt;/code    &gt; represents a list node with the recursive call's result already in place. So we might look for a function like&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;cata ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (ListF a b -&amp;gt; b) -&amp;gt; List a -&amp;gt; b&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;If we had this, we could write&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;sumF ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Num&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) =&amp;gt; List a -&amp;gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;sumF = cata f &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f Nil = &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f (Cons x xs) = x + xs&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The function &lt;code    &gt;f&lt;/code    &gt; specifies one step of reduction, and the magical function &lt;code    &gt;cata&lt;/code    &gt; handles the rest.&lt;/p  &gt;&lt;p  &gt;The recursion pattern captured by &lt;code    &gt;cata&lt;/code    &gt; is very similar to &lt;code    &gt;foldr&lt;/code    &gt; on the built-in list type. In fact, we can implement &lt;code    &gt;foldr&lt;/code    &gt; with &lt;code    &gt;cata&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;foldrF ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (a -&amp;gt; b -&amp;gt; b) -&amp;gt; b -&amp;gt; List a -&amp;gt; b&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;foldrF f z = cata g &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  g Nil = z&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  g (Cons x xs) = f x xs&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;If &lt;code    &gt;foldr&lt;/code    &gt; is good enough, then what's so special about &lt;code    &gt;cata&lt;/code    &gt;? The answer is that &lt;code    &gt;cata&lt;/code    &gt; actually has this very general type:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;cata ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Functor&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f) =&amp;gt; (f a -&amp;gt; a) -&amp;gt; Fix f -&amp;gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;I'll give the one-line definition of &lt;code    &gt;cata&lt;/code    &gt; later. Writing it yourself is a fun puzzle.&lt;/p  &gt;&lt;p  &gt;We can see that we'll need this instance:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Functor&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (ListF a) &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; _ Nil         = Nil&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f (Cons x xs) = Cons x (f xs)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This &lt;code    &gt;fmap&lt;/code    &gt; just takes a function and applies it to the &lt;code    &gt;self&lt;/code    &gt;-typed field, if any. It's not recursive and has no relation to the &lt;code    &gt;[]&lt;/code    &gt; instance of &lt;code    &gt;Functor&lt;/code    &gt;, for which &lt;code    &gt;fmap = map&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="folding-natural-numbers"&gt;&lt;h1  &gt;Folding natural numbers&lt;/h1  &gt;&lt;p  &gt;Let's put our generic &lt;code    &gt;cata&lt;/code    &gt; to good use on another type. Every &lt;a href="http://en.wikipedia.org/wiki/Natural_number"    &gt;natural number&lt;/a    &gt; is either zero, or the successor of another natural number:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; NaturalF self = Zero | Succ self&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural = Fix NaturalF&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Again, &lt;code    &gt;fmap&lt;/code    &gt; applies a function to each &lt;code    &gt;self&lt;/code    &gt;-typed field:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Functor&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; NaturalF &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; _ Zero     = Zero&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f (Succ v) = Succ (f v)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We can then use &lt;code    &gt;cata&lt;/code    &gt; to define conversion to &lt;code    &gt;Integer&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;fromNatural ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Integer&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;fromNatural = cata f &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f Zero     = &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f (Succ n) = &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; + n&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;as well as addition and multiplication:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;add ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural -&amp;gt; Natural -&amp;gt; Natural&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;add n = cata f &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f Zero     = n&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f (Succ m) = In $ Succ m&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;mul ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Natural -&amp;gt; Natural -&amp;gt; Natural&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;mul n = cata f &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f Zero     = In Zero&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f (Succ m) = add n m&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Testing it:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;GHCi&amp;gt; fromNatural (add (toNatural 2) (mul (toNatural 3) (toNatural 5)))17&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="folding-rose-trees"&gt;&lt;h1  &gt;Folding rose trees&lt;/h1  &gt;&lt;p  &gt;Let's try one more structure, namely rose trees:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; TreeF a self = Node a [self]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Tree  a      = Fix (TreeF a)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Functor&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (TreeF a) &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f (Node v xs) = Node v (&lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f xs)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;As before, &lt;code    &gt;fmap&lt;/code    &gt; applies a function to each &lt;code    &gt;self&lt;/code    &gt;-typed field. Since we have a list of these, we use &lt;code    &gt;map&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;We define some traversals:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;valuesF ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Tree a -&amp;gt; [a]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;valuesF = cata (\(Node x xs) -&amp;gt; x : &lt;/span      &gt;&lt;span class="Function"      &gt;concat&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; xs)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;depthF ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Tree a -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Integer&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;depthF = cata (\(Node _ xs) -&amp;gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; + &lt;/span      &gt;&lt;span class="Function"      &gt;maximum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;:xs))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;and test them:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;GHCi&amp;gt; let n x = In . Node xGHCi&amp;gt; let t1 = n 'a' []GHCi&amp;gt; valuesF t1&amp;quot;a&amp;quot;GHCi&amp;gt; depthF t11GHCi&amp;gt; let t2 = n 'a' [n 'b' [], n 'c' [n 'd' []], n 'e' []]GHCi&amp;gt; valuesF t2&amp;quot;abcde&amp;quot;GHCi&amp;gt; depthF t23&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="the-definition-of-cata"&gt;&lt;h1  &gt;The definition of &lt;code    &gt;cata&lt;/code    &gt;&lt;/h1  &gt;&lt;p  &gt;As promised:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;cata ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Functor&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f) =&amp;gt; (f a -&amp;gt; a) -&amp;gt; Fix f -&amp;gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;cata g = g . &lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (cata g) . out&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="generic-programming"&gt;&lt;h1  &gt;Generic programming&lt;/h1  &gt;&lt;p  &gt;We usually manipulate data because we care about its &lt;em    &gt;meaning&lt;/em    &gt;. But some operations only depend on the data's &lt;em    &gt;structure&lt;/em    &gt;. If we have some complex nested data value, we might want to pretty-print it, or serialize it with &lt;a href="http://hackage.haskell.org/package/binary"    &gt;binary&lt;/a    &gt;, or collect all the &lt;code    &gt;String&lt;/code    &gt;s buried within. These are concepts which apply to any data type you like. Shouldn't our code be similarly adaptable?&lt;/p  &gt;&lt;p  &gt;This idea is called &lt;em    &gt;generic programming&lt;/em    &gt;. Implementations in Haskell include &lt;a href="http://hackage.haskell.org/package/syb"    &gt;syb&lt;/a    &gt;, &lt;a href="http://hackage.haskell.org/package/uniplate"    &gt;uniplate&lt;/a    &gt;, &lt;a href="http://hackage.haskell.org/package/multiplate"    &gt;multiplate&lt;/a    &gt;, &lt;a href="http://hackage.haskell.org/package/instant-generics"    &gt;instant-generics&lt;/a    &gt;, &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/users_guide/generic-classes.html"    &gt;GHC's built-in support&lt;/a    &gt;, and &lt;a href="http://hackage.haskell.org/packages/archive/pkg-list.html#cat:generics"    &gt;many other efforts&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;Each of these libraries demands certain information about each data type, and in return provides some generic operations. In this view, our above development of &lt;code    &gt;Fix&lt;/code    &gt; constitutes a really tiny generics library. We require&lt;/p  &gt;&lt;ul class="incremental"  &gt;&lt;li    &gt;that you write recursive types as &lt;code      &gt;Fix F&lt;/code      &gt;, where &lt;code      &gt;F&lt;/code      &gt; is non-recursive, and&lt;/li    &gt;&lt;li    &gt;that you provide &lt;code      &gt;instance Functor F&lt;/code      &gt;.&lt;/li    &gt;&lt;/ul  &gt;&lt;p  &gt;In return, you get the single generic operation &lt;code    &gt;cata&lt;/code    &gt;, which reduces a recursive structure to a &amp;quot;summary&amp;quot; value, by replacing each constructor with an arbitrary computation.&lt;/p  &gt;&lt;p  &gt;Our toy generics library is simple, but it doesn't actually save much work. Using &lt;code    &gt;Fix&lt;/code    &gt; adds noise to the code, and our &lt;code    &gt;Functor&lt;/code    &gt; instances aren't much shorter than a custom fold function for each type. Conversely, our uses of &lt;code    &gt;cata&lt;/code    &gt; aren't much simpler than explicit recursive traversals.&lt;/p  &gt;&lt;p  &gt;Practicality aside, I think it's cool to define folding &amp;quot;once and for all&amp;quot;. I'm interested to learn (from you!) what else can be done with &lt;code    &gt;Fix&lt;/code    &gt;'d data or similar techniques.&lt;/p  &gt;&lt;p  &gt;For a non-trivial generics library built around similar ideas, see &lt;a href="http://hackage.haskell.org/package/multirec"    &gt;multirec&lt;/a    &gt; and the accompanying paper.&lt;/p  &gt;&lt;/div&gt;&lt;div id="odds-and-ends"&gt;&lt;h1  &gt;Odds and ends&lt;/h1  &gt;&lt;div id="nomenclature"  &gt;&lt;h2    &gt;Nomenclature&lt;/h2    &gt;&lt;p    &gt;&lt;code      &gt;Fix&lt;/code      &gt; is sometimes named &lt;code      &gt;Mu&lt;/code      &gt;, because the Greek letter &lt;a href="http://en.wikipedia.org/wiki/Mu_(letter)"      &gt;μ&lt;/a      &gt; is used to represent least fixed points.&lt;/p    &gt;&lt;p    &gt;&lt;code      &gt;cata&lt;/code      &gt; stands for &lt;a href="http://knol.google.com/k/catamorphisms"      &gt;catamorphism&lt;/a      &gt;.&lt;/p    &gt;&lt;p    &gt;Some of this stuff shows up in &lt;a href="http://www.willamette.edu/~fruehr/haskell/evolution.html"      &gt;&amp;quot;Evolution of a Haskell Programmer&amp;quot;&lt;/a      &gt;. They build a factorial function using not only catamorphisms but also zygomorphisms and paramorphisms. Tell your friends!&lt;/p    &gt;&lt;p    &gt;In &lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/"      &gt;&lt;em &gt;TaPL&lt;/em &gt;&lt;/a      &gt; there's a discussion of equirecursive versus isorecursive type systems. Haskell is in the latter category. &lt;code      &gt;Fix f&lt;/code      &gt; is isomorphic to, but not equivalent to, &lt;code      &gt;f (Fix f)&lt;/code      &gt;. The functions &lt;code      &gt;In&lt;/code      &gt; and &lt;code      &gt;out&lt;/code      &gt; provide the isomorphism. If we defined &lt;code      &gt;Fix&lt;/code      &gt; using &lt;code      &gt;data&lt;/code      &gt; instead of &lt;code      &gt;newtype&lt;/code      &gt;, the isomorphism would fail because of the extra value &lt;code      &gt;In &amp;#8869;&lt;/code      &gt;.&lt;/p    &gt;&lt;/div  &gt;&lt;div id="isomorphisms"  &gt;&lt;h2    &gt;Isomorphisms&lt;/h2    &gt;&lt;p    &gt;&lt;code      &gt;NaturalF&lt;/code      &gt; is isomorphic to &lt;code      &gt;Maybe&lt;/code      &gt;:&lt;/p    &gt;&lt;pre class="sourceCode haskell"    &gt;&lt;code      &gt;&lt;span class="Keyword" &gt;data&lt;/span &gt;&lt;span class="Normal NormalText" &gt; NaturalF self = Zero    | Succ self&lt;/span &gt;&lt;br  /&gt;&lt;span class="Keyword" &gt;data&lt;/span &gt;&lt;span class="Normal NormalText" &gt; &lt;/span &gt;&lt;span class="DataType TypeConstructor" &gt;Maybe&lt;/span &gt;&lt;span class="Normal NormalText" &gt;    a    = &lt;/span &gt;&lt;span class="Keyword DataConstructor" &gt;Nothing&lt;/span &gt;&lt;span class="Normal NormalText" &gt; | &lt;/span &gt;&lt;span class="Keyword DataConstructor" &gt;Just&lt;/span &gt;&lt;span class="Normal NormalText" &gt; a&lt;/span &gt;&lt;br  /&gt;&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;The &lt;code      &gt;Functor&lt;/code      &gt; instances are also the same.&lt;/p    &gt;&lt;p    &gt;&lt;code      &gt;NaturalF&lt;/code      &gt; is also isomorphic to &lt;code      &gt;ListF ()&lt;/code      &gt;, ignoring undefined values.&lt;/p    &gt;&lt;/div  &gt;&lt;div id="ghc-tricks"  &gt;&lt;h2    &gt;GHC tricks&lt;/h2    &gt;&lt;p    &gt;While the above is standard Haskell, we can pull a few more tricks by using a couple of GHC extensions.&lt;/p    &gt;&lt;p    &gt;GHC could help us reduce boilerplate by &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#deriving-typeable"      &gt;deriving &lt;code &gt;Functor&lt;/code &gt; instances&lt;/a      &gt;.&lt;/p    &gt;&lt;p    &gt;With some GHC extensions, we can write &lt;code      &gt;Show&lt;/code      &gt; for &lt;code      &gt;Fix&lt;/code      &gt;:&lt;/p    &gt;&lt;pre class="sourceCode haskell"    &gt;&lt;code      &gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (f (Fix f))) =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (Fix f) &lt;/span &gt;&lt;span class="Keyword" &gt;where&lt;/span &gt;&lt;br  /&gt;&lt;span class="Normal NormalText" &gt;  &lt;/span &gt;&lt;span class="Function" &gt;showsPrec&lt;/span &gt;&lt;span class="Normal NormalText" &gt; p (In x) = &lt;/span &gt;&lt;span class="Function" &gt;showParen&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (p &amp;gt;= &lt;/span &gt;&lt;span class="DecVal Decimal" &gt;11&lt;/span &gt;&lt;span class="Normal NormalText" &gt;) (&lt;/span &gt;&lt;span class="Function" &gt;showString&lt;/span &gt;&lt;span class="Normal NormalText" &gt; &lt;/span &gt;&lt;span class="String" &gt;&amp;quot;In &amp;quot;&lt;/span &gt;&lt;span class="Normal NormalText" &gt; . &lt;/span &gt;&lt;span class="Function" &gt;showsPrec&lt;/span &gt;&lt;span class="Normal NormalText" &gt; &lt;/span &gt;&lt;span class="DecVal Decimal" &gt;11&lt;/span &gt;&lt;span class="Normal NormalText" &gt; x)&lt;/span &gt;&lt;br  /&gt;&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;Testing it:&lt;/p    &gt;&lt;pre    &gt;&lt;code      &gt;GHCi&amp;gt; toNatural 3In (Succ (In (Succ (In (Succ (In Zero))))))&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;This requires &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#instance-rules"      &gt;&lt;code &gt;-XFlexibleContexts&lt;/code &gt;&lt;/a      &gt; &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/users_guide/type-class-extensions.html#undecidable-instances"      &gt;&lt;code &gt;-XUndecidableInstances&lt;/code &gt;&lt;/a      &gt;. The latter is required because &lt;code      &gt;f (Fix f)&lt;/code      &gt; is a syntactically larger type than &lt;code      &gt;Fix f&lt;/code      &gt;, so GHC can't convince itself that instance resolution will definitely terminate. For well-behaved arguments to &lt;code      &gt;Fix&lt;/code      &gt;, it works out. We'll have something like&lt;/p    &gt;&lt;pre class="sourceCode haskell"    &gt;&lt;code      &gt;&lt;span class="Comment" &gt;-- from above&lt;/span &gt;&lt;br  /&gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (f (Fix f)))&lt;/span &gt;&lt;br  /&gt;&lt;span class="Normal NormalText" &gt;       =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (Fix f)&lt;/span &gt;&lt;br  /&gt;&lt;br  /&gt;&lt;span class="Comment" &gt;-- from 'deriving (Show)' on NaturalF&lt;/span &gt;&lt;br  /&gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; self)&lt;/span &gt;&lt;br  /&gt;&lt;span class="Normal NormalText" &gt;       =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (NaturalF self)&lt;/span &gt;&lt;br  /&gt;&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;which instantiates to&lt;/p    &gt;&lt;pre class="sourceCode haskell"    &gt;&lt;code      &gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (NaturalF (Fix NaturalF)))&lt;/span &gt;&lt;br  /&gt;&lt;span class="Normal NormalText" &gt;       =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (Fix NaturalF)&lt;/span &gt;&lt;br  /&gt;&lt;br  /&gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (Fix NaturalF))&lt;/span &gt;&lt;br  /&gt;&lt;span class="Normal NormalText" &gt;       =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (NaturalF (Fix NaturalF))&lt;/span &gt;&lt;br  /&gt;&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;and GHC is clever enough to resolve the mutual recursion.&lt;/p    &gt;&lt;p    &gt;Remarkably, GHC can &lt;em      &gt;derive&lt;/em      &gt; this instance with &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#stand-alone-deriving"      &gt;&lt;code &gt;-XStandaloneDeriving&lt;/code &gt;&lt;/a      &gt;:&lt;/p    &gt;&lt;pre class="sourceCode haskell"    &gt;&lt;code      &gt;&lt;span class="Keyword" &gt;deriving&lt;/span &gt;&lt;span class="Normal NormalText" &gt; &lt;/span &gt;&lt;span class="Keyword" &gt;instance&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (&lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (f (Fix f))) =&amp;gt; &lt;/span &gt;&lt;span class="Keyword Class" &gt;Show&lt;/span &gt;&lt;span class="Normal NormalText" &gt; (Fix f)&lt;/span &gt;&lt;br  /&gt;&lt;/code      &gt;&lt;/pre    &gt;&lt;p    &gt;That's how I got the precedence-correct code above, via &lt;code      &gt;-ddump-deriv&lt;/code      &gt;.&lt;/p    &gt;&lt;/div  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-3677942817296436337?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/3677942817296436337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/12/type-level-fix-and-generic-folds.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3677942817296436337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/3677942817296436337'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/12/type-level-fix-and-generic-folds.html' title='Type-level Fix and generic folds'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-7457424889542322462</id><published>2010-11-04T18:52:00.000-07:00</published><updated>2010-11-05T12:10:42.664-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='donttrythisathome'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Obtaining the name of a function in Haskell</title><content type='html'>&lt;p&gt;Someone on &lt;a href="http://www.haskell.org/haskellwiki/IRC_channel"  &gt;&lt;code    &gt;#haskell&lt;/code    &gt;&lt;/a  &gt; asked whether you could recover a function's name from its value, i.e.&lt;/p&gt;&lt;pre&gt;&lt;code  &gt;GHCi&amp;gt; name id&amp;quot;id&amp;quot;GHCi&amp;gt; name map&amp;quot;map&amp;quot;&lt;/code  &gt;&lt;/pre&gt;&lt;p&gt;This is easy in some languages. But Haskell is not designed to provide this kind of run-time information. We'll need some non-portable hacks. I tested this code with GHC 6.12.1 on &lt;code  &gt;amd64&lt;/code  &gt; Linux; see below for portability notes.&lt;/p&gt;&lt;div id="how-it-works"&gt;&lt;h1  &gt;How it works&lt;/h1  &gt;&lt;p  &gt;Most values in GHC Haskell are represented by a &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"    &gt;closure&lt;/a    &gt;. Closures representing functions are common in functional-language compilers, but GHC extends the idea to cover &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#Typesofobject"    &gt;many other sorts&lt;/a    &gt; of values.&lt;/p  &gt;&lt;p  &gt;Closures exist to store data. But the run-time system also needs operational information about each closure: how to garbage-collect it, how to force its evaluation, etc. This information is known at compile time and is shared between many closures. All algebraic values with the same constructor will share this information, as will all function values created from the same lambda in the program's source.&lt;/p  &gt;&lt;p  &gt;So each closure stores a pointer to an &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/HeapObjects#InfoTables"    &gt;info table&lt;/a    &gt;, holding this operational information. Info tables are generated at compile time, and stored as part of an executable's read-only data section. This means that they have statically-known addresses, with associated names in the executable's symbol table. We'll use these symbol names to name our functions.&lt;/p  &gt;&lt;p  &gt;We can dump an executable's symbol table with &lt;code    &gt;nm&lt;/code    &gt;:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ nm -f posix foo...ghczmprim_GHCziBool_Bool_closure_tbl D 0000000000749978 ghczmprim_GHCziBool_False_closure D 0000000000749970 ghczmprim_GHCziBool_False_static_info T 00000000004e4dd8 ghczmprim_GHCziBool_True_closure D 0000000000749990 ghczmprim_GHCziBool_True_static_info T 00000000004e4d80 ghczmprim_GHCziDebug_debugErrLn1_closure D 00000000007499a0 ghczmprim_GHCziDebug_debugErrLn1_info T 00000000004e4ec0 ...&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Haskell identifiers can contain characters not allowed in symbol names. GHC uses a &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames"    &gt;name-mangling scheme&lt;/a    &gt; to build symbol names. For example, the first symbol above decodes to&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;ghc-prim_GHC.Bool_Bool_closure_tbl&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="reading-the-symbols"&gt;&lt;h1  &gt;Reading the symbols&lt;/h1  &gt;&lt;p  &gt;We'll use &lt;a href="http://hackage.haskell.org/package/vacuum"    &gt;vacuum&lt;/a    &gt; to inspect heap objects. vacuum can do a lot of cool things, like &lt;a href="http://hackage.haskell.org/package/vacuum-cairo"    &gt;visualize heap structures&lt;/a    &gt; from a running Haskell program. We'll only use one of vacuum's functions here.&lt;/p  &gt;&lt;p  &gt;We'll also use the &lt;a href="http://www.haskell.org/haskellwiki/GHC/As_a_library"    &gt;GHC API&lt;/a    &gt; to un-mangle symbol names. GHC is a 20-year effort that has evolved alongside the Haskell language. It follows some legacy conventions like a mostly-flat module hierarchy. So the module we need is named simply &lt;code    &gt;Encoding&lt;/code    &gt;.&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Word&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Maybe&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Text.Printf&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Control.Parallel&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ( pseq )&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;           &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Map&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;System.Posix.Files&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Posix&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;System.Process&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;     &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Proc&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Foreign.Ptr&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;        &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Ptr&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;GHC.Vacuum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Vac&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Encoding           &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; GHC&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We invoke &lt;code    &gt;nm&lt;/code    &gt; as a subprocess and parse its output:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Symbols = &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Map.Map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Word &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;getSymbols ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Symbols&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;getSymbols = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  exe &amp;lt;- Posix.readSymbolicLink &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;/proc/self/exe&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  out &amp;lt;- Proc.readProcess &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;nm&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;-f&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;posix&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, exe] &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; offset = &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0x10&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; f (sym:_:addr:_) = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Function"      &gt;read&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;0x&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;++addr) - offset, GHC.zDecodeString sym)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      f _ = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Nothing&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Function"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; . Map.fromList . catMaybes . &lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (f . &lt;/span      &gt;&lt;span class="Function"      &gt;words&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;) . &lt;/span      &gt;&lt;span class="Function"      &gt;lines&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $ out&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We're using the Linux &lt;a href="http://manpages.courier-mta.org/htmlman5/proc.5.html"    &gt;&lt;code      &gt;proc&lt;/code      &gt;&lt;/a    &gt; filesystem to get a symbolic link to our application's executable.&lt;/p  &gt;&lt;p  &gt;The symbols in memory appear at an address &lt;code    &gt;0x10&lt;/code    &gt; = 16 bytes or 2 machine words lower than in the executable's symbol table. I'm not sure why; perhaps it's because of GHC's &amp;quot;tables next to code&amp;quot; optimization.&lt;/p  &gt;&lt;/div&gt;&lt;div id="resolving-a-symbol"&gt;&lt;h1  &gt;Resolving a symbol&lt;/h1  &gt;&lt;p  &gt;Once we have the symbol table, looking up a value is relatively easy:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;name ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Symbols -&amp;gt; a -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;name syms x = fromMaybe unk $ Map.&lt;/span      &gt;&lt;span class="Function"      &gt;lookup&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ptr syms &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ptr = x &lt;/span      &gt;&lt;span class="Others InfixOperator"      &gt;`pseq`&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Function"      &gt;fromIntegral&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; . Ptr.ptrToWordPtr . Vac.getInfoPtr $ x)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  unk = printf &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;&amp;lt;unknown info table at 0x%016x&amp;gt;&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ptr&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We use vacuum to get the value's info table pointer, convert this to a &lt;code    &gt;Word&lt;/code    &gt;, then look it up in the symbol table.&lt;/p  &gt;&lt;p  &gt;We explicitly evaluate &lt;code    &gt;x&lt;/code    &gt; with &lt;code    &gt;pseq&lt;/code    &gt;, to avoid seeing a thunk.&lt;/p  &gt;&lt;/div&gt;&lt;div id="testing-it"&gt;&lt;h1  &gt;Testing it&lt;/h1  &gt;&lt;p  &gt;We'll test with&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ ghc --make name.hs -package ghc$ ./name&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Each test below is commented with the expected output. First, let's try a few non-function values:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;main ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ()&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;main = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  syms &amp;lt;- getSymbols&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; test = &lt;/span      &gt;&lt;span class="Function"      &gt;putStrLn&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; . name syms&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;3&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;            &lt;/span      &gt;&lt;span class="Comment"      &gt;-- integer-gmp_GHC.Integer.Type_S#_con_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test (&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;3&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; :: &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)   &lt;/span      &gt;&lt;span class="Comment"      &gt;-- ghc-prim_GHC.Types_I#_static_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;xyz&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;        &lt;/span      &gt;&lt;span class="Comment"      &gt;-- ghc-prim_GHC.Types_:_con_info&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;GHC defaults to &lt;code    &gt;3 :: Integer&lt;/code    &gt;, as &lt;code    &gt;-Wall&lt;/code    &gt; will tell you. As we see, &lt;code    &gt;Integer&lt;/code    &gt; and &lt;code    &gt;Int&lt;/code    &gt; are both implemented as algebraic data:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Integer&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  = S# Int#&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  | J# Int# ByteArray#&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; = I# Int#&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The string &lt;code    &gt;&amp;quot;xyz&amp;quot;&lt;/code    &gt; is a list built out of &lt;code    &gt;(:)&lt;/code    &gt; cells.&lt;/p  &gt;&lt;p  &gt;Next let's try a few functions:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;  test &lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;          &lt;/span      &gt;&lt;span class="Comment"      &gt;-- base_GHC.Base_map_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test &lt;/span      &gt;&lt;span class="Function"      &gt;getChar&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;      &lt;/span      &gt;&lt;span class="Comment"      &gt;-- base_System.IO_getChar_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test (+)          &lt;/span      &gt;&lt;span class="Comment"      &gt;-- integer-gmp_GHC.Integer_plusInteger_info&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Not bad! &lt;code    &gt;(+)&lt;/code    &gt; defaults to operating on &lt;code    &gt;Integer&lt;/code    &gt;, and GHC inlines the type class dictionary, giving us the underlying &lt;code    &gt;plusInteger&lt;/code    &gt; function.&lt;/p  &gt;&lt;p  &gt;Now let's see the limits of this technique:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;  test (\_ -&amp;gt; &lt;/span      &gt;&lt;span class="Char"      &gt;'x'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)  &lt;/span      &gt;&lt;span class="Comment"      &gt;-- s1jD_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test (&lt;/span      &gt;&lt;span class="Function"      &gt;const&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Char"      &gt;'x'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)  &lt;/span      &gt;&lt;span class="Comment"      &gt;-- stg_PAP_info&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  test test         &lt;/span      &gt;&lt;span class="Comment"      &gt;-- stg_PAP_info&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Our lambda expression gets a useless compiler-generated name. The application of &lt;code    &gt;const&lt;/code    &gt; is worse; it uses an info table common to all partial applications. However, we could use vacuum to follow the fields of the &lt;code    &gt;PAP&lt;/code    &gt; closure, which I'll leave as an exercise to the reader. ;)&lt;/p  &gt;&lt;p  &gt;&lt;code    &gt;test&lt;/code    &gt; itself is also a partial application. It's defined by applying two arguments to the function &lt;code    &gt;(.)&lt;/code    &gt; defined as&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;(.) f g x = f (g x)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;If we eta-expand &lt;code    &gt;test&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; test x = &lt;/span      &gt;&lt;span class="Function"      &gt;putStrLn&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $ name syms x&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;then we'll get another compiler-generated name like &lt;code    &gt;s1mh_info&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="notes"&gt;&lt;h1  &gt;Notes&lt;/h1  &gt;&lt;p  &gt;This is a hack, and probably not suitable for any serious purpose. Shelling out to &lt;code    &gt;nm&lt;/code    &gt; to get a symbol table is particularly ugly. I tried to use &lt;a href="http://hackage.haskell.org/package/bindings-bfd"    &gt;bindings to BFD&lt;/a    &gt;, but ran into some segfaults.&lt;/p  &gt;&lt;p  &gt;The above code will work only on 64-bit machines, but could be adapted for 32-bit. I bet the magic offset would change. It works on GHC 6.12.1, and should work on other recent versions, if you can get vacuum to build.&lt;/p  &gt;&lt;p  &gt;It definitely requires a Unix system, and specifically Linux or something emulating Linux's &lt;code    &gt;proc&lt;/code    &gt; filesystem. You'll need &lt;code    &gt;nm&lt;/code    &gt; from &lt;a href="http://www.gnu.org/software/binutils/"    &gt;GNU Binutils&lt;/a    &gt;, which is standard on a system configured for C development.&lt;/p  &gt;&lt;p  &gt;It won't work if you run &lt;code    &gt;strip&lt;/code    &gt; on your binaries...&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-7457424889542322462?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/7457424889542322462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/11/obtaining-name-of-function-in-haskell.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7457424889542322462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/7457424889542322462'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/11/obtaining-name-of-function-in-haskell.html' title='Obtaining the name of a function in Haskell'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-1851116579612501474</id><published>2010-10-26T01:03:00.000-07:00</published><updated>2010-11-16T12:21:13.302-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='detrospector'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Tour of a real toy Haskell program, part 2</title><content type='html'>&lt;p&gt;This is part 2 of my commentary on &lt;a href="http://hackage.haskell.org/package/detrospector"  &gt;detrospector&lt;/a  &gt;. You can find part 1 &lt;a href="http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-1.html"  &gt;here&lt;/a  &gt;.&lt;/p&gt;&lt;div id="performance-claims"&gt;&lt;h1  &gt;Performance claims&lt;/h1  &gt;&lt;p  &gt;I make a lot of claims about performance below, not all of which are supported by evidence. I did perform a fair amount of profiling, but it's impossible to test every combination of data structures. How can I structure my code to make more of my performance hypotheses easily testable?&lt;/p  &gt;&lt;/div&gt;&lt;div id="representing-the-source-document"&gt;&lt;h1  &gt;Representing the source document&lt;/h1  &gt;&lt;p  &gt;When we process a source document, we'll need a data structure to represent large amounts of text.&lt;/p  &gt;&lt;ul class="incremental"  &gt;&lt;li    &gt;&lt;p      &gt;Haskell's standard &lt;code &gt;String&lt;/code &gt; type is simple, maximally lazy, and Unicode-correct. However, as a singly-linked list of individually boxed heap-allocated characters, it's woefully inefficient in space and time.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;a href="http://hackage.haskell.org/package/bytestring" &gt;&lt;code   &gt;ByteString&lt;/code   &gt;&lt;/a &gt; is a common alternative, but solves the wrong problem. We need a sequence of Unicode codepoints, not a sequence of bytes.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;a href="http://hackage.haskell.org/packages/archive/bytestring/0.9.1.7/doc/html/Data-ByteString-Char8.html" &gt;&lt;code   &gt;ByteString.Char8&lt;/code   &gt;&lt;/a &gt; is a hack and not remotely Unicode-correct.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;The &lt;a href="http://hackage.haskell.org/package/text" &gt;text&lt;/a &gt; library stores Unicode characters in a &lt;code &gt;ByteString&lt;/code &gt;-like packed format. That's exactly what we need.&lt;/p      &gt;&lt;/li    &gt;&lt;/ul  &gt;&lt;p  &gt;For more information on picking a string type, see &lt;a href="http://blog.ezyang.com/2010/08/strings-in-haskell/"    &gt;ezyang's writeup&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;We choose the &lt;a href="http://hackage.haskell.org/packages/archive/text/0.10.0.0/doc/html/Data-Text-Lazy.html"    &gt;lazy flavor&lt;/a    &gt; of text so that we can stream the input file in chunks without storing it all in memory. Lazy IO is semantically dubious, but I've decided that this project is enough of a toy that I don't care. Note that robustness to IO errors is not in the requirements list. ;)&lt;/p  &gt;&lt;p  &gt;The &lt;a href="http://hackage.haskell.org/package/enumerator"    &gt;enumerator&lt;/a    &gt; package provides iteratees as a composable, well-founded alternative to the lazy IO hack. The enumerator API was complex enough to put me off using it for the first version of detrospector. After reading &lt;a href="http://docs.yesodweb.com/blog/enumerators-tutorial-part-1/"    &gt;Michael Snoyman's enumerators tutorial&lt;/a    &gt;, I have a slight idea how the library works, and I might use it in a future version.&lt;/p  &gt;&lt;/div&gt;&lt;div id="representing-substrings"&gt;&lt;h1  &gt;Representing substrings&lt;/h1  &gt;&lt;p  &gt;We also need to represent the &lt;em    &gt;k&lt;/em    &gt;-character substrings, both when we analyze the source and when we generate text. The requirements here are different.&lt;/p  &gt;&lt;p  &gt;We expect that &lt;em    &gt;k&lt;/em    &gt; will be small, certainly under 10 — otherwise, you'll just generate the source document! With many small strings, the penalty of boxing each individual &lt;code    &gt;Char&lt;/code    &gt; is less severe.&lt;/p  &gt;&lt;p  &gt;And we need to support queue-like operations; we build a new substring by pushing a character onto the end, and dropping one from the beginning. For both &lt;code    &gt;String&lt;/code    &gt; and &lt;code    &gt;Text&lt;/code    &gt;, appending onto the end requires a full copy. So we'll use &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/containers-0.3.0.0/Data-Sequence.html"    &gt;&lt;code      &gt;Data.Sequence&lt;/code      &gt;&lt;/a    &gt;, which provides sequences with bidirectional append, implemented as &lt;a href="http://comonad.com/reader/2010/finger-trees/"    &gt;finger trees&lt;/a    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Queue a = &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;S.Seq&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;...Actually, I just ran a quick test with &lt;code    &gt;Text&lt;/code    &gt; as the queue type, and it seems not to matter much. Since &lt;em    &gt;k&lt;/em    &gt; is small, the &lt;em    &gt;O&lt;/em    &gt;(&lt;em    &gt;k&lt;/em    &gt;) copy is insignificant. Profiling makes fools of us all, and asymptotic analysis is mostly misused. Anyway, I'm keeping the code the way it is, pending any insight from my clever readers. Perhaps one of the queues from &lt;em    &gt;&lt;a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504"      &gt;Purely Functional Data Structures&lt;/a      &gt;&lt;/em    &gt; would be most appropriate.&lt;/p  &gt;&lt;/div&gt;&lt;div id="representing-character-counts"&gt;&lt;h1  &gt;Representing character counts&lt;/h1  &gt;&lt;p  &gt;We need a data structure for tabulating character counts. In the old days of C and Eurocentrism, we could use a flat, mutable &lt;code    &gt;int[256]&lt;/code    &gt; indexed by ASCII values. But the range of Unicode characters is far too large for a flat array, and we need efficient functional updates without a full copy.&lt;/p  &gt;&lt;p  &gt;We could import &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/containers-0.3.0.0/Data-Map.html"    &gt;&lt;code      &gt;Data.Map&lt;/code      &gt;&lt;/a    &gt; and use &lt;code    &gt;Map Char Int&lt;/code    &gt;. This will build a balanced binary search tree using pairwise &lt;code    &gt;Ord&lt;/code    &gt; comparisons.&lt;/p  &gt;&lt;p  &gt;But we can do better. We can use the bits of an integer key as a path in a tree, following a left or right child for a &lt;code    &gt;0&lt;/code    &gt; or &lt;code    &gt;1&lt;/code    &gt; bit, respectively. This sort of search tree (a &lt;a href="http://en.wikipedia.org/wiki/Trie"    &gt;trie&lt;/a    &gt;) will typically outperform repeated pairwise comparisons. &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/containers-0.3.0.0/Data-IntMap.html"    &gt;&lt;code      &gt;Data.IntMap&lt;/code      &gt;&lt;/a    &gt; implements this idea, with an API very close to &lt;code    &gt;Map Int&lt;/code    &gt;. Our keys are &lt;code    &gt;Char&lt;/code    &gt;s, but we can easily convert using &lt;code    &gt;fromIntegral&lt;/code    &gt;.&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.IntMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; IM&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; FreqTable = &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;IM.IntMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="representing-distributions"&gt;&lt;h1  &gt;Representing distributions&lt;/h1  &gt;&lt;p  &gt;So we have some frequency table like&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;IM.fromList [(&lt;/span      &gt;&lt;span class="Char"      &gt;'e'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;267&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;), (&lt;/span      &gt;&lt;span class="Char"      &gt;'t'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;253&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;), (&lt;/span      &gt;&lt;span class="Char"      &gt;'a'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;219&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;), ...]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;How can we efficiently pick a character from this distribution? We're mapping characters to individual counts, but we really want a map from &lt;em    &gt;cumulative&lt;/em    &gt; counts to characters:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PickTable = PickTable &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;IM.IntMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Char&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;To sample a character from &lt;code    &gt;PickTable t im&lt;/code    &gt;, we first pick a random &lt;code    &gt;k&lt;/code    &gt; such that 0 ≤ &lt;code    &gt;k&lt;/code    &gt; &amp;lt; &lt;code    &gt;t&lt;/code    &gt;, using a uniform distribution. We then find the first key in &lt;code    &gt;im&lt;/code    &gt; which is greater than &lt;code    &gt;k&lt;/code    &gt;, and take its associated &lt;code    &gt;Char&lt;/code    &gt; value. In code:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;System.Random.MWC&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; RNG&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;sample ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PickTable -&amp;gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;RNG.GenIO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Char&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;sample (PickTable t im) g = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  k &amp;lt;- (&lt;/span      &gt;&lt;span class="Others InfixOperator"      &gt;`mod`&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; t) &amp;lt;$&amp;gt; RNG.uniform g&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;case&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; IM.split k im &lt;/span      &gt;&lt;span class="Keyword"      &gt;of&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    (_, IM.toList -&amp;gt; ((_,x):_)) -&amp;gt; &lt;/span      &gt;&lt;span class="Function"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    _ -&amp;gt; &lt;/span      &gt;&lt;span class="Function"      &gt;error&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;impossible&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The largest cumulative sum is the total count &lt;code    &gt;t&lt;/code    &gt;, so the largest key in &lt;code    &gt;im&lt;/code    &gt; is &lt;code    &gt;t&lt;/code    &gt;. We know &lt;code    &gt;k&lt;/code    &gt; &amp;lt; &lt;code    &gt;t&lt;/code    &gt;, so &lt;code    &gt;IM.split k im&lt;/code    &gt; will never return an empty map on the right side.&lt;/p  &gt;&lt;p  &gt;Note the &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/syntax-extns.html#view-patterns"    &gt;view pattern&lt;/a    &gt; for pattern-matching an &lt;code    &gt;IntMap&lt;/code    &gt; as if it were an ascending-order list.&lt;/p  &gt;&lt;p  &gt;The standard &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/random-1.0.0.2/System-Random.html"    &gt;&lt;code      &gt;System.Random&lt;/code      &gt;&lt;/a    &gt; library in GHC Haskell is quite slow, a problem shared by most language implementations. We use the much faster &lt;a href="http://hackage.haskell.org/package/mwc-random"    &gt;mwc-random&lt;/a    &gt; package. The only operation we need is picking a uniform &lt;code    &gt;Int&lt;/code    &gt; as an &lt;code    &gt;IO&lt;/code    &gt; action.&lt;/p  &gt;&lt;p  &gt;We still need a way to build our &lt;code    &gt;PickTable&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.List&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ( mapAccumR )&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;cumulate ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; FreqTable -&amp;gt; PickTable&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;cumulate t = PickTable r $ IM.fromList ps &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  (r,ps) = mapAccumR f &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $ IM.assocs t&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  f ra (x,n) = &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; rb = ra+n &lt;/span      &gt;&lt;span class="Keyword"      &gt;in&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (rb, (rb, &lt;/span      &gt;&lt;span class="Function"      &gt;toEnum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This code is short, but kind of tricky. For reference:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;mapAccumR ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (acc -&amp;gt; x -&amp;gt; (acc, y)) -&amp;gt; acc -&amp;gt; [x] -&amp;gt; (acc, [y])&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;f ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;) -&amp;gt; (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Char&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;&lt;code    &gt;f&lt;/code    &gt; takes an assoc pair from the &lt;code    &gt;FreqTable&lt;/code    &gt;, adds its count to the running sum, and produces an assoc pair for the &lt;code    &gt;PickTable&lt;/code    &gt;. We start the traversal with a sum of &lt;code    &gt;0&lt;/code    &gt;, and get the final sum &lt;code    &gt;r&lt;/code    &gt; along with our assoc pairs &lt;code    &gt;ps&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="representing-the-markov-chain"&gt;&lt;h1  &gt;Representing the Markov chain&lt;/h1  &gt;&lt;p  &gt;So we can represent probability distributions for characters. Now we need a map from &lt;em    &gt;k&lt;/em    &gt;-character substrings to distributions.&lt;/p  &gt;&lt;p  &gt;&lt;code    &gt;Data.Map&lt;/code    &gt; is again an option, but pairwise, character-wise comparison of our &lt;code    &gt;Queue Char&lt;/code    &gt; values will be slow. What we really want is another trie, with character-based fanout at each node. Hackage has &lt;a href="http://hackage.haskell.org/package/bytestring-trie"    &gt;bytestring-trie&lt;/a    &gt;, which unfortunately works on bytes, not characters. And maybe I should have used &lt;a href="http://hackage.haskell.org/package/TrieMap"    &gt;TrieMap&lt;/a    &gt; or &lt;a href="http://hackage.haskell.org/package/list-tries"    &gt;list-tries&lt;/a    &gt;. Instead I used the &lt;a href="http://hackage.haskell.org/package/hashmap"    &gt;hashmap&lt;/a    &gt; package:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.HashMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; H&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Chain = Chain &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;H.HashMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (Queue &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Char&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;) PickTable)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;A value &lt;code    &gt;Chain k hm&lt;/code    &gt; maps from subsequences of up to &lt;code    &gt;k&lt;/code    &gt; &lt;code    &gt;Char&lt;/code    &gt;s to &lt;code    &gt;PickTable&lt;/code    &gt;s. A lookup of some &lt;code    &gt;Queue Char&lt;/code    &gt; key will require one traversal to calculate an &lt;code    &gt;Int&lt;/code    &gt; hash value, then uses an &lt;code    &gt;IntMap&lt;/code    &gt; to find a (hopefully small) &lt;code    &gt;Map&lt;/code    &gt; of keys with that same hash value.&lt;/p  &gt;&lt;p  &gt;There is a wrinkle: we need to specify how to hash a &lt;code    &gt;Queue&lt;/code    &gt;, which is just a synonym for &lt;code    &gt;S.Seq&lt;/code    &gt;. This is an &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/separate-compilation.html#orphan-modules"    &gt;orphan instance&lt;/a    &gt;, which we could avoid by &lt;code    &gt;newtype&lt;/code    &gt;-wrapping &lt;code    &gt;S.Seq&lt;/code    &gt;.&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Hashable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; H&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Foldable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; F&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;H.Hashable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) =&amp;gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;H.Hashable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;S.Seq&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Comment"      &gt;{-# SPECIALIZE instance H.Hashable (S.Seq Char) #-}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  hash = F.foldl' (\acc h -&amp;gt; acc &lt;/span      &gt;&lt;span class="Others InfixOperator"      &gt;`H.combine`&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; H.hash h) &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This code is lifted almost verbatim from the &lt;code    &gt;[a]&lt;/code    &gt; instance in &lt;a href="http://hackage.haskell.org/packages/archive/hashable/1.0.0/doc/html/src/Data-Hashable.html#Hashable"    &gt;&lt;code      &gt;Data.Hashable&lt;/code      &gt;&lt;/a    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="serialization"&gt;&lt;h1  &gt;Serialization&lt;/h1  &gt;&lt;p  &gt;After training, we need to write the &lt;code    &gt;Chain&lt;/code    &gt; to disk, for use in subsequent generation. I started out with derived &lt;code    &gt;Show&lt;/code    &gt; and &lt;code    &gt;Read&lt;/code    &gt;, which was simple but incredibly slow. We'll use &lt;a href="http://hackage.haskell.org/package/binary"    &gt;binary&lt;/a    &gt; with &lt;a href="http://hackage.haskell.org/packages/archive/bytestring/0.9.1.7/doc/html/Data-ByteString-Lazy.html"    &gt;&lt;code      &gt;ByteString.Lazy&lt;/code      &gt;&lt;/a    &gt; — the dreaded lazy IO again!&lt;/p  &gt;&lt;p  &gt;We start by specifying how to serialize a few types. Here the tuple instances for &lt;code    &gt;Binary&lt;/code    &gt; come in handy:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Bin&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Comment"      &gt;-- another orphan instance&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Bin.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; k, &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Bin.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; v, &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;H.Hashable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; k, &lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Ord&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; k)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;       =&amp;gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Bin.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (&lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;H.HashMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; k v) &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  put = Bin.put . H.assocs&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  get = H.fromList &amp;lt;$&amp;gt; Bin.get&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Bin.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PickTable &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  put (PickTable n t) = Bin.put (n,t)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  get = &lt;/span      &gt;&lt;span class="Function"      &gt;uncurry&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; PickTable &amp;lt;$&amp;gt; Bin.get&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;instance&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Bin.Binary&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Chain &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  put (Chain n h) = Bin.put (n,h)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  get = &lt;/span      &gt;&lt;span class="Function"      &gt;uncurry&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Chain &amp;lt;$&amp;gt; Bin.get&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The actual IO is easy. We use &lt;a href="http://hackage.haskell.org/package/zlib"    &gt;gzip&lt;/a    &gt; compression, which fits right into the IO pipeline:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Types&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.ByteString.Lazy&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;   &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; BSL&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Codec.Compression.GZip&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Z&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;withChain ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Function"      &gt;FilePath&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; (Chain -&amp;gt; RNG -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;withChain p f = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ch &amp;lt;- (Bin.decode . Z.decompress) &amp;lt;$&amp;gt; BSL.&lt;/span      &gt;&lt;span class="Function"      &gt;readFile&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; p&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  RNG.withSystemRandom $ f ch&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;writeChain ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Function"      &gt;FilePath&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; -&amp;gt; Chain -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ()&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;writeChain out = BSL.&lt;/span      &gt;&lt;span class="Function"      &gt;writeFile&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; out . Z.compress . Bin.encode&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="training-the-chain"&gt;&lt;h1  &gt;Training the chain&lt;/h1  &gt;&lt;p  &gt;I won't present the whole implementation of the &lt;code    &gt;train&lt;/code    &gt; subcommand, but here's a simplification:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Modes.Train&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Text&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;     &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Txt&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Text.IO&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Txt&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.HashMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; H&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.IntMap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;   &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; IM&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Sequence&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; S&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;Data.Foldable&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; F&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;train Train{num,out} = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  (_,h) &amp;lt;- Txt.foldl' roll (emptyQ, H.empty) ys &amp;lt;$&amp;gt; Txt.&lt;/span      &gt;&lt;span class="Function"      &gt;getContents&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  writeChain out . Chain num $ H.&lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; cumulate h &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  roll (!s,!h) x&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    = (shift num x s, F.&lt;/span      &gt;&lt;span class="Function"      &gt;foldr&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (H.alter $ ins x) h $ S.tails s)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ins x &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Nothing&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $! sing x&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ins x (&lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; v) = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $! incr x v&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  sing x = IM.singleton (&lt;/span      &gt;&lt;span class="Function"      &gt;fromEnum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x) &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  incr x = IM.alter f $ &lt;/span      &gt;&lt;span class="Function"      &gt;fromEnum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    f &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Nothing&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    f (&lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; v) = &lt;/span      &gt;&lt;span class="Keyword DataConstructor"      &gt;Just&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; $! (v&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;+1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Before generating &lt;code    &gt;PickTable&lt;/code    &gt;s, we build a &lt;code    &gt;HashMap&lt;/code    &gt; of &lt;code    &gt;FreqTable&lt;/code    &gt;s. We fold over the input text, accumulating a pair of (last characters seen, map so far). Since &lt;code    &gt;foldl'&lt;/code    &gt; is only strict to &lt;a href="http://foldoc.org/Weak+Head+Normal+Form"    &gt;weak head-normal form&lt;/a    &gt; (WHNF), we use &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/bang-patterns.html"    &gt;bang patterns&lt;/a    &gt; on the fold function &lt;code    &gt;roll&lt;/code    &gt; to force further evaluation. &lt;em    &gt;RWH&lt;/em    &gt; discusses &lt;a href="http://book.realworldhaskell.org/read/profiling-and-optimization.html#id678593"    &gt;the same issue&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;&lt;code    &gt;shift&lt;/code    &gt; (from &lt;code    &gt;Detrospector.Types&lt;/code    &gt;) pushes a new character into the queue, and drops the oldest character if the size exceeds &lt;code    &gt;num&lt;/code    &gt;. We add one count for the new character &lt;code    &gt;x&lt;/code    &gt;, both for the whole history &lt;code    &gt;s&lt;/code    &gt; and each of its suffixes.&lt;/p  &gt;&lt;p  &gt;We're using &lt;code    &gt;alter&lt;/code    &gt; where perhaps a combination of &lt;code    &gt;lookup&lt;/code    &gt; and &lt;code    &gt;insert&lt;/code    &gt; would be more natural. This is a workaround for a subtle laziness-related space leak, which I found after much profiling and random mucking about. When you insert into a map like so:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; mm = insert k (v&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;+1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;) m&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;there is nothing to force &lt;code    &gt;v+1&lt;/code    &gt; to WHNF, &lt;em    &gt;even if you force&lt;/em    &gt; &lt;code    &gt;mm&lt;/code    &gt; to WHNF. The leaves of our tree end up holding large thunks of the form &lt;code    &gt;((((1+1)+1)+1)+...)&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;The workaround is to call &lt;code    &gt;alter&lt;/code    &gt; with &lt;code    &gt;Just $! (v+1)&lt;/code    &gt;. We know that the implementation of &lt;code    &gt;alter&lt;/code    &gt; will pattern-match on the &lt;code    &gt;Maybe&lt;/code    &gt; constructor, which then triggers WHNF evaluation of &lt;code    &gt;v+1&lt;/code    &gt; because of &lt;code    &gt;($!)&lt;/code    &gt;. This was tricky to figure out. Is there a better solution, or some different way I should approach this problem? It seems to me that &lt;code    &gt;Data.Map&lt;/code    &gt; and friends are generally lacking in strictness building blocks.&lt;/p  &gt;&lt;/div&gt;&lt;div id="the-end"&gt;&lt;h1  &gt;The end!&lt;/h1  &gt;&lt;p  &gt;Thanks for reading! Here's an example of how &lt;em    &gt;not&lt;/em    &gt; to write the same program:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;module&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Main &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;{&lt;/span      &gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Random;(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;:y)%(R p _)=y%p;(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;:f)%(R _ n)=f%n;[]%(J x)=x;b&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;[p,v,k]=(l k%).(l v%).(l p%);main=&lt;/span      &gt;&lt;span class="Function"      &gt;getContents&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;&amp;gt;&amp;gt;=(&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;eek&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;#).&lt;/span      &gt;&lt;span class="Function"      &gt;flip&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;(.:&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;eek&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)(y.y.y.y$&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;);h k=&lt;/span      &gt;&lt;span class="Function"      &gt;toEnum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; k;;(r:j).:[k,v,b]=(j.:[v,b,r]).((k?).(v?).(b?)$(r?)m);[].:_=&lt;/span      &gt;&lt;span class="Function"      &gt;id&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;;(!)=&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function"      &gt;iterate&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;;&lt;/span      &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; R a=J a|R(R a)(R a);(&amp;amp;)i=&lt;/span      &gt;&lt;span class="Function"      &gt;fmap&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; i;k b y v j=&lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;{t=l b%v+y;d f|t&amp;gt;j=b;d&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;f=k(m b)t v j}&lt;/span      &gt;&lt;span class="Keyword"      &gt;in&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; d q;y l=(!!&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;8&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)(q R!J l);q(+)b=b+b;p(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;:v)z(R f x)=R(p v z f)x;p[]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;z(J x)=J(z x);p(&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;:v)z(R n k)=R n$p v z k;m = &lt;/span      &gt;&lt;span class="Function"      &gt;succ&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;;l p=&lt;/span      &gt;&lt;span class="Function"      &gt;tail&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;.(&lt;/span      &gt;&lt;span class="Function"      &gt;snd&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;&amp;amp;).&lt;/span      &gt;&lt;span class="Function"      &gt;take&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;9&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;$((&amp;lt;&amp;lt;&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;2&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;).&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function"      &gt;fst&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)!(&lt;/span      &gt;&lt;span class="Function"      &gt;fromEnum&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; p,&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;);(?)=p.l;d@[q,p,r]#v=&lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;{u=b d v;j=i u;(s,o)|j&amp;lt;&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;=((&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;97&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;122&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;),&lt;/span      &gt;&lt;span class="Function"      &gt;id&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;)|h &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;=((&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,j&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;-1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;),(k &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; u))}&lt;/span      &gt;&lt;span class="Keyword"      &gt;in&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;{q&amp;lt;-(h.o)&amp;amp;randomRIO s;&lt;/span      &gt;&lt;span class="Function"      &gt;putChar&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; q;[p,r,q]#v};i(J q)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;=q;i(R n k)=i n+i k;(&amp;lt;&amp;lt;)=&lt;/span      &gt;&lt;span class="Function"      &gt;divMod&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;} &lt;/span      &gt;&lt;span class="Comment"      &gt;-- finite text on stdin  &amp;#169; keegan oct 2010 BSD3&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-1851116579612501474?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/1851116579612501474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/1851116579612501474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/1851116579612501474'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-2.html' title='Tour of a real toy Haskell program, part 2'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4433114012653136846</id><published>2010-10-26T01:00:00.000-07:00</published><updated>2010-10-26T01:06:21.182-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='detrospector'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Tour of a real toy Haskell program, part 1</title><content type='html'>&lt;p&gt;Haskell suffers from a problem I'll call the Fibonacci Gap. Many beginners start out with a bunch of &lt;a href="http://projecteuler.net/"  &gt;small mathematical exercises&lt;/a  &gt;, develop that skillset, and then are at a loss for what to study next. Often they'll ask in &lt;a href="http://www.haskell.org/haskellwiki/IRC_channel"  &gt;&lt;code    &gt;#haskell&lt;/code    &gt;&lt;/a  &gt; for an example of a &amp;quot;real Haskell program&amp;quot; to study. Typical responses include the examples in &lt;a href="http://book.realworldhaskell.org/read/"  &gt;&lt;em    &gt;Real World Haskell&lt;/em    &gt;&lt;/a  &gt;, or the &lt;a href="http://xmonad.wordpress.com/2009/09/09/the-design-and-implementation-of-xmonad/"  &gt;Design and Implementation of XMonad&lt;/a  &gt; talk.&lt;/p&gt;&lt;p&gt;This is my attempt to provide another data point: a commentary on &lt;a href="http://hackage.haskell.org/package/detrospector"  &gt;detrospector&lt;/a  &gt;, my text-generating toy. It's perhaps between the &lt;em  &gt;RWH&lt;/em  &gt; examples and xmonad in terms of size and complexity. It's not a large program, and certainly not very &lt;em  &gt;useful&lt;/em  &gt;, but it does involve a variety of real-world concerns such as Unicode processing, choice of data structures, strictness for performance, command-line arguments, serialization, etc. It also illustrates my particular coding style, which I don't claim is the One True Way, but which has served me well in a variety of Haskell projects over the past five years.&lt;/p&gt;&lt;p&gt;Of course, I imagine that experts may disagree with some of my decisions, and I welcome any and all feedback.&lt;/p&gt;&lt;p&gt;I haven't put hyperlinked source online yet, but you can grab &lt;a href="http://hackage.haskell.org/packages/archive/detrospector/0.1/detrospector-0.1.tar.gz"  &gt;the tarball&lt;/a  &gt; and follow along.&lt;/p&gt;&lt;p&gt;This is part 1, covering style and high-level design. &lt;a href="http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-2.html"  &gt;Part 2&lt;/a  &gt; addresses more details of algorithms, data structures, performance, etc.&lt;/p&gt;&lt;div id="the-algorithm"&gt;&lt;h1  &gt;The algorithm&lt;/h1  &gt;&lt;p  &gt;detrospector generates random text conforming to the general style and diction of a given source document, using a &lt;a href="http://www.google.com/search?num=100&amp;amp;q=markov%20chain%20text"    &gt;quite common&lt;/a    &gt; algorithm.&lt;/p  &gt;&lt;p  &gt;First, pick a &amp;quot;window size&amp;quot; &lt;em    &gt;k&lt;/em    &gt;. We consider all &lt;em    &gt;k&lt;/em    &gt;-character contiguous substrings of the source document. For each substring &lt;em    &gt;w&lt;/em    &gt;, we want to know the probability distribution of the next character. In other words, we want to compute values for&lt;/p  &gt;&lt;blockquote  &gt;&lt;p    &gt;&lt;em      &gt;P&lt;/em      &gt;(next char is &lt;em      &gt;x&lt;/em      &gt; | last &lt;em      &gt;k&lt;/em      &gt; chars were &lt;em      &gt;w&lt;/em      &gt;).&lt;/p    &gt;&lt;/blockquote  &gt;&lt;p  &gt;To compute these, we scan through the source document, remembering the last &lt;em    &gt;k&lt;/em    &gt; characters as &lt;em    &gt;w&lt;/em    &gt;. We build a table of next-character occurrence counts for each substring &lt;em    &gt;w&lt;/em    &gt;.&lt;/p  &gt;&lt;p  &gt;These tables form a &lt;a href="http://en.wikipedia.org/wiki/Markov_chain"    &gt;Markov chain&lt;/a    &gt;, and we can generate random text by a random walk in this chain. If the last &lt;em    &gt;k&lt;/em    &gt; characters we generated were &lt;em    &gt;w&lt;/em    &gt;, we choose the next character randomly according to the observed distribution for &lt;em    &gt;w&lt;/em    &gt;.&lt;/p  &gt;&lt;p  &gt;So we can train it on &lt;a href="http://www.antipope.org/charlie/blog-static/fiction/accelerando/accelerando.html"    &gt;&lt;em      &gt;Accelerando&lt;/em      &gt;&lt;/a    &gt; and get output like:&lt;/p  &gt;&lt;blockquote  &gt;&lt;p    &gt;addressed to tell using back holes everyone third of the glances waves and diverging him into the habitat. Far beyond Neptune, I be?&amp;quot; asks, grimy. Who's whether is headquarters I need a Frenchwoman's boyfriend go place surrected in the whole political-looking on the room, leaving it, beam, the wonderstood. The Chromosome of upload, does enough. If this one of the Vile catches agree.&amp;quot;&lt;/p    &gt;&lt;/blockquote  &gt;&lt;/div&gt;&lt;div id="design-requirements"&gt;&lt;h1  &gt;Design requirements&lt;/h1  &gt;&lt;p  &gt;We can only understand a program's design in light of the problem it was meant to solve. Here's my informal list of requirements:&lt;/p  &gt;&lt;ul class="incremental"  &gt;&lt;li    &gt;&lt;p      &gt;detrospector should generate random text according to the above algorithm.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;We should be able to invoke the text generator many times without re-analyzing the source text each time.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;detrospector should handle all Unicode characters, using the character encoding specified by the system's locale.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;detrospector should be fast without sacrificing clarity, whatever that means.&lt;/p      &gt;&lt;/li    &gt;&lt;/ul  &gt;&lt;p  &gt;Wearing my customer hat, these are axioms without justification. Wearing my implementor hat, I will have to justify design decisions in these terms.&lt;/p  &gt;&lt;/div&gt;&lt;div id="style"&gt;&lt;h1  &gt;Style&lt;/h1  &gt;&lt;p  &gt;In general I import modules &lt;code    &gt;qualified&lt;/code    &gt;, using &lt;code    &gt;as&lt;/code    &gt; to provide a short local name. I make an exception for other modules in the same project, and for &amp;quot;standard modules&amp;quot;. I don't have a precise definition of &amp;quot;standard module&amp;quot; but it includes things like &lt;code    &gt;Data.Maybe&lt;/code    &gt;, &lt;code    &gt;Control.Applicative&lt;/code    &gt;, etc.&lt;/p  &gt;&lt;p  &gt;The longest line in detrospector is 70 characters. There is no hard limit, but more than about 90 is suspect.&lt;/p  &gt;&lt;p  &gt;Indentation is two spaces. Tabs are absolutely forbidden. I don't let the indentation of a block construct depend on the length of a name, thus:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;foo x = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  y &amp;lt;- bar x&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  baz y&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;and&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;bar x =&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;let&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; y = baz x&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      z = quux x y&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;in&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;  y z&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This avoids absurd left margins, looks more uniform, and is easier to edit.&lt;/p  &gt;&lt;p  &gt;I usually write delimited syntax with one item per line, with the delimiter prefixed:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;{-# LANGUAGE&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Comment"      &gt;    ViewPatterns&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Comment"      &gt;  , PatternGuards #-}&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;and&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Mode&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  = Train { &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;num   ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;          , &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;out   ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Function"      &gt;FilePath&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; }&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  | Run   { &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;chain ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Function"      &gt;FilePath&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; }&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Overriding layout is sometimes useful, e.g.:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;look = &lt;/span      &gt;&lt;span class="Keyword"      &gt;do&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; x &amp;lt;- H.&lt;/span      &gt;&lt;span class="Function"      &gt;lookup&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; t h; &lt;/span      &gt;&lt;span class="Function"      &gt;return&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (x, S.&lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; t)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;(With &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/syntax-extns.html#tuple-sections"    &gt;&lt;code      &gt;-XTupleSections&lt;/code      &gt;&lt;/a    &gt; we could write&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;look = (,S.&lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; t) &amp;lt;$&amp;gt; H.&lt;/span      &gt;&lt;span class="Function"      &gt;lookup&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; t h&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;but that's just gratuitous.)&lt;/p  &gt;&lt;p  &gt;I always write type signatures on top-level bindings, but rarely elsewhere.&lt;/p  &gt;&lt;/div&gt;&lt;div id="module-structure"&gt;&lt;h1  &gt;Module structure&lt;/h1  &gt;&lt;p  &gt;I started out with a single file, which quickly became unmanageable. The current module layout is:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;Detrospector.  Types      types and functions used throughout  Modes      a type with one constructor per mode  Modes.    Train    train the Markov chain    Run      generate random text    Neolog   generate neologisms  Main       command-line parsing&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;There is also a &lt;code    &gt;Main&lt;/code    &gt; module in &lt;code    &gt;detrospector.hs&lt;/code    &gt;, which simply invokes &lt;code    &gt;Detrospector.Main.main&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;Modules I write tend to fall into two categories: those which export nearly everything, and those which export only one or two things. The former includes &amp;quot;utility&amp;quot; modules with lots of small types and function definitions. The latter includes modules providing a specific piece of functionality. A parsing module might define three dozen parsers internally, but will only export the root of the grammar.&lt;/p  &gt;&lt;p  &gt;An abstract data type might fall into a third category, since they can export a large API yet have lots of internal helpers. But I don't write such modules very often.&lt;/p  &gt;&lt;p  &gt;&lt;code    &gt;Detrospector.Types&lt;/code    &gt; is in the first category. Most Haskell projects will have a &lt;code    &gt;Types&lt;/code    &gt; module, although I'm somewhat disappointed that I let this one become a general grab-bag of types and utility functions.&lt;/p  &gt;&lt;p  &gt;The rest fall into the second category. Each module in &lt;code    &gt;Detrospector.Modes.*&lt;/code    &gt; exports one function to handle that mode. &lt;code    &gt;Detrospector.Main&lt;/code    &gt; exports only &lt;code    &gt;main&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="build-setup"&gt;&lt;h1  &gt;Build setup&lt;/h1  &gt;&lt;p  &gt;This was actually my first Cabal project, and the first thing I uploaded to &lt;a href="http://hackage.haskell.org/packages/hackage.html"    &gt;Hackage&lt;/a    &gt;. I think Cabal is great, and features like package-visibility management are useful even for small local projects.&lt;/p  &gt;&lt;p  &gt;In my &lt;code    &gt;cabal&lt;/code    &gt; file I set &lt;code    &gt;ghc-options: -Wall&lt;/code    &gt;, which enables many helpful warnings. The project should build with no warnings, but I use the &lt;code    &gt;OPTIONS_GHC&lt;/code    &gt; pragma to disable specific warnings in specific files, where necessary.&lt;/p  &gt;&lt;p  &gt;I also run &lt;a href="http://community.haskell.org/~ndm/hlint/"    &gt;HLint&lt;/a    &gt; on my code periodically, but I don't have it integrated with Cabal.&lt;/p  &gt;&lt;p  &gt;I was originally passing &lt;code    &gt;-O2&lt;/code    &gt; to &lt;code    &gt;ghc&lt;/code    &gt;. Cabal complained that it's probably not necessary, which was correct. The Cabal default of &lt;code    &gt;-O&lt;/code    &gt; performs just as well.&lt;/p  &gt;&lt;p  &gt;I'm using &lt;a href="http://git-scm.com/"    &gt;Git&lt;/a    &gt; for source control, which is neither here nor there.&lt;/p  &gt;&lt;/div&gt;&lt;div id="command-line-parsing"&gt;&lt;h1  &gt;Command-line parsing&lt;/h1  &gt;&lt;p  &gt;detrospector currently has three modes, as listed above. I wanted to use the &amp;quot;subcommand&amp;quot; model of &lt;code    &gt;git&lt;/code    &gt;, &lt;code    &gt;cabal&lt;/code    &gt;, etc. So we have &lt;code    &gt;detrospector train&lt;/code    &gt;, &lt;code    &gt;detrospector run&lt;/code    &gt;, etc. The &lt;a href="http://hackage.haskell.org/package/cmdargs"    &gt;cmdargs&lt;/a    &gt; package handles this argument style with a low level of boilerplate.&lt;/p  &gt;&lt;p  &gt;The &amp;quot;impure&amp;quot; interface to cmdargs uses some dark magic in the operator &lt;a href="http://hackage.haskell.org/packages/archive/cmdargs/0.6.1/doc/html/System-Console-CmdArgs-Implicit.html#v:-38--61-"    &gt;&lt;code      &gt;&amp;amp;=&lt;/code      &gt;&lt;/a    &gt; in order to attach annotations to arbitrary record fields. The various caveats made me uneasy, so I opted for the slightly more verbose &amp;quot;pure&amp;quot; interface, which looks like this:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;-- module Detrospector.Main&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;qualified&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;System.Console.CmdArgs&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="Keyword"      &gt;as&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Arg&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;import&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;           &lt;/span      &gt;&lt;span class="Normal ModuleName"      &gt;System.Console.CmdArgs&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;((+=),Annotate((:=)))&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;...&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;modes  = Arg.modes_  [train,run,neolog]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      += Arg.program &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;detrospector&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      += Arg.summary &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;detrospector: Markov chain text generator&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;      += Arg.help    &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Build and run Markov chains for text generation&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  &lt;/span      &gt;&lt;span class="Keyword"      &gt;where&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  train = Arg.record Train{}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    [ num := &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;4&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;          += Arg.help &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Number of characters lookback&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    , out := &lt;/span      &gt;&lt;span class="Function"      &gt;error&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Must specify output chain&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;          += Arg.typFile&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;          += Arg.help &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Write chain to this file&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    += Arg.help &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Train a Markov chain from standard input&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  run = Arg.record Run{}&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    [ chain := &lt;/span      &gt;&lt;span class="Function"      &gt;error&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Must specify input chain&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;            += Arg.argPos &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;0&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;         &lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;            += Arg.typ &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;CHAIN_FILE&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; ]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;    += Arg.help &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;Generate random text&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  ...&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;This tells cmdargs how to construct values of my record type &lt;code    &gt;Detrospector.Modes.Mode&lt;/code    &gt;. We get help output for free:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;$ ./dist/build/detrospector/detrospector -?detrospector: Markov chain text generatordetrospector [COMMAND] ... [OPTIONS]  Build and run Markov chains for text generationCommon flags:  -? --help        Display help message  -V --version     Print version informationdetrospector train [OPTIONS]  Train a Markov chain from standard input  -n --num=INT     Number of characters lookback  -o --out=FILE    Write chain to this filedetrospector run [OPTIONS] CHAIN_FILE  Generate random text...&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;My use of &lt;code    &gt;error&lt;/code    &gt; here is hacky and leads to a bug that I recently discovered. When the &lt;code    &gt;-o&lt;/code    &gt; argument to &lt;code    &gt;train&lt;/code    &gt; is invalid or missing, the error is not printed until the (potentially time-consuming) analysis is completed. Only then is the record's field forced.&lt;/p  &gt;&lt;/div&gt;&lt;div id="to-be-continued..."&gt;&lt;h1  &gt;To be continued...&lt;/h1  &gt;&lt;p  &gt;&lt;a href="http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-2.html"    &gt;...right this way.&lt;/a    &gt;&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4433114012653136846?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4433114012653136846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4433114012653136846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4433114012653136846'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/tour-of-real-toy-haskell-program-part-1.html' title='Tour of a real toy Haskell program, part 1'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-4018128849794453516</id><published>2010-10-23T00:21:00.000-07:00</published><updated>2010-10-23T00:21:04.919-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compose'/><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Typing mathematical characters in X</title><content type='html'>&lt;p&gt;Unicode provides many useful characters for mathematics. If you've studied the traditional notation, an expression like « Γ ⊢ Λt.λ(x:t).x : ∀t. t → t » is much more readable than an ASCII equivalent. However, most systems don't provide an easy way to enter these characters.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Compose_key"  &gt;compose key&lt;/a  &gt; feature of X Windows provides a nice solution on Linux and other UNIX systems. Compose combinations are easy-to-remember mnemonics, like &lt;code  &gt;-&amp;gt;&lt;/code  &gt; for →, and an enormous number of characters are available with just a few keystrokes.&lt;/p&gt;&lt;div id="setting-it-up"&gt;&lt;h1  &gt;Setting it up&lt;/h1  &gt;&lt;p  &gt;I cooked up a &lt;a href="http://github.com/kmcallister/math-compose/blob/master/XCompose"    &gt;config file&lt;/a    &gt; with my most-used mathematical symbols. With recent Xorg, you can drop this file in &lt;code    &gt;~/.XCompose&lt;/code    &gt;, restart X, and you should be good to go.&lt;/p  &gt;&lt;p  &gt;The &lt;code    &gt;include&lt;/code    &gt; line will pull in your system-wide configuration, e.g. &lt;code    &gt;/usr/share/X11/locale/en_US.UTF-8/Compose&lt;/code    &gt;. This already contains many useful characters. I was going to add &lt;code    &gt;&amp;lt;3&lt;/code    &gt; for ♥ and &lt;code    &gt;CCCP&lt;/code    &gt; for ☭, but I found that Debian already provides these.&lt;/p  &gt;&lt;p  &gt;GTK has its own input handling. To make it defer to X, I had to add an environment variable in &lt;code    &gt;~/.xsession&lt;/code    &gt;:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;export GTK_IM_MODULE=&amp;quot;xim&amp;quot;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The &amp;quot;Fn&amp;quot; key on recent ThinkPads makes a good compose key. It normally acts as a modifier key in hardware, but will send a keycode to X when pressed and released by itself. I used this &lt;code    &gt;xmodmap&lt;/code    &gt; setting:&lt;/p  &gt;&lt;pre  &gt;&lt;code    &gt;keycode 151=Multi_key&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="tweaking-the-codes"&gt;&lt;h1  &gt;Tweaking the codes&lt;/h1  &gt;&lt;p  &gt;Being boilerplate-averse, I specified the key combinations in a &lt;a href="http://github.com/kmcallister/math-compose/blob/master/compose.in"    &gt;compact format&lt;/a    &gt; which is processed by &lt;a href="http://github.com/kmcallister/math-compose/blob/master/mk-compose.hs"    &gt;this Haskell script&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;Obviously, not everyone will like my choice of key combinations. If you tweak the file and come up with something particularly nice, I'd like to see it. If you can't run Haskell code for whatever reason, it's not too hard to edit the generated &lt;code    &gt;XCompose&lt;/code    &gt; file.&lt;/p  &gt;&lt;p  &gt;Though my use of Haskell here may seem gratuitous, I actually started writing this script in Python, but ran into trouble with Python 2's inconsistent treatment of Unicode text. Using Haskell's &lt;code    &gt;String&lt;/code    &gt; type with GHC ≥ 6.12 will Just Work, at least until you care about performance.&lt;/p  &gt;&lt;/div&gt;&lt;div id="alternatives"&gt;&lt;h1  &gt;Alternatives&lt;/h1  &gt;&lt;p  &gt;If you don't like this solution, &lt;a href="http://www.scim-im.org/"    &gt;SCIM&lt;/a    &gt; provides an input mode which uses &lt;a href="http://en.wikipedia.org/wiki/LaTeX"    &gt;&lt;span class="latex"&gt;L&lt;sup&gt;a&lt;/sup&gt;T&lt;sub&gt;e&lt;/sub&gt;X&lt;/span&gt;&lt;/a    &gt; codes.&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-4018128849794453516?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/4018128849794453516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/typing-mathematical-characters-in-x.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4018128849794453516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/4018128849794453516'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/typing-mathematical-characters-in-x.html' title='Typing mathematical characters in X'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-1507115966516523671</id><published>2010-10-19T18:18:00.000-07:00</published><updated>2010-10-20T04:00:38.617-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='type-theory'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Quantification in Haskell</title><content type='html'>&lt;p&gt;I wrote an answer over at &lt;a href="http://stackoverflow.com/questions/tagged/haskell"  &gt;Stack Overflow&lt;/a  &gt; that somehow grew to article length. Here it is, recorded for posterity.&lt;/p&gt;&lt;p&gt;I'll paraphrase the original question as:&lt;/p&gt;&lt;ul class="incremental"&gt;&lt;li  &gt;&lt;p    &gt;What's the difference between the types &lt;code      &gt;forall a. [a]&lt;/code      &gt; and &lt;code      &gt;[forall a. a]&lt;/code      &gt;, and&lt;/p    &gt;&lt;/li  &gt;&lt;li  &gt;&lt;p    &gt;How does this relate to existential types?&lt;/p    &gt;&lt;/li  &gt;&lt;/ul&gt;&lt;p&gt;Well, the short answer to the second question is &amp;quot;It doesn't relate&amp;quot;. But there's still a natural flow in discussing both topics.&lt;/p&gt;&lt;div id="notation"&gt;&lt;h1  &gt;Notation&lt;/h1  &gt;&lt;p  &gt;Polymorphic values are essentially functions on types, but Haskell's syntax leaves both type abstraction and type application implicit. To better understand what's going on, we'll use a pidgin syntax of Haskell combined with a typed lambda calculus like &lt;a href="http://en.wikipedia.org/wiki/System_F"    &gt;System F&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;In System F, polymorphism involves explicit type abstractions and type application. For example, the familiar &lt;code    &gt;map&lt;/code    &gt; function would be written as:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; :: &amp;#8704;a. &amp;#8704;b. (a &amp;#8594; b) &amp;#8594; [a] &amp;#8594; [b]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; = &amp;#923;a. &amp;#923;b. &amp;#955;(&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;f ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a &amp;#8594; b). &amp;#955;(&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;xs ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [a]). &lt;/span      &gt;&lt;span class="Keyword"      &gt;case&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; xs &lt;/span      &gt;&lt;span class="Keyword"      &gt;of&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  [] &amp;#8594; []&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  (y:ys) &amp;#8594; f y : &lt;/span      &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @a @b f ys&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;&lt;code    &gt;map&lt;/code    &gt; is now a function of &lt;em    &gt;four&lt;/em    &gt; arguments: types &lt;code    &gt;a&lt;/code    &gt; and &lt;code    &gt;b&lt;/code    &gt;, a function, and a list.&lt;/p  &gt;&lt;p  &gt;At the term level, we have one new syntactic form: Λ (upper-case lambda). A polymorphic value is a function from types to values, written &lt;code    &gt;&amp;#923;x. e&lt;/code    &gt;, much as a function from values to values is written &lt;code    &gt;&amp;#955;x. e&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;At the type level, we have the symbol ∀ (&amp;quot;for all&amp;quot;), corresponding to GHC's &lt;code    &gt;forall&lt;/code    &gt; keyword. A term containing Λ gives rise to a type containing ∀, just as a term containing λ gives rise to a type containing →.&lt;/p  &gt;&lt;p  &gt;Since we have functions of types, we also need application of types. I use the notation &lt;code    &gt;@a&lt;/code    &gt; (as in GHC Core) to denote application of a type argument. So we might use &lt;code    &gt;map&lt;/code    &gt; like so:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function"      &gt;map&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @Char @Int &lt;/span      &gt;&lt;span class="Function"      &gt;ord&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;xzy&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Note also that I've provided an explicit type on each λ abstraction. Type inference for System F is, in general, undecidable (&lt;a href="http://www.macs.hw.ac.uk/~jbw/papers/#Wells:APAL-1999-v98"    &gt;Wells, 1999&lt;/a    &gt;). The restricted form of polymorphism available in vanilla &lt;a href="http://www.haskell.org/onlinereport/"    &gt;Haskell 98&lt;/a    &gt; has decidable inference, but you lose this if you enable certain GHC extensions like &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/other-type-extensions.html#universal-quantification"    &gt;&lt;code      &gt;RankNTypes&lt;/code      &gt;&lt;/a    &gt;.&lt;/p  &gt;&lt;p  &gt;We don't need annotations on Λ abstractions, because we have only one &amp;quot;kind&amp;quot; of type. In actual Haskell, or a calculus like System Fω, we also have type constructors, and we need a system of &lt;a href="http://www.haskell.org/onlinereport/decls.html#sect4.1.1"    &gt;kinds&lt;/a    &gt; to describe how they combine. We'll ignore this issue here.&lt;/p  &gt;&lt;p  &gt;So a value of polymorphic type is like a function from types to values. The caller of a polymorphic function gets to choose a type argument, and the function must comply.&lt;/p  &gt;&lt;p  &gt;One last bit of notation: I'll use the syntax&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&amp;#8869;@t&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;to mean an undefined value of type &lt;code    &gt;t&lt;/code    &gt;, similar to Haskell's &lt;code    &gt;undefined&lt;/code    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div id="a.-a"&gt;&lt;h1  &gt;∀a. [a]&lt;/h1  &gt;&lt;p  &gt;How, then, would we write a term of type &lt;code    &gt;&amp;#8704;a. [a]&lt;/code    &gt;? We know that types containing ∀ come from terms containing Λ:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;term1 ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &amp;#8704;a. [a]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term1 = &amp;#923;a. ?&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Within the body marked &lt;code    &gt;?&lt;/code    &gt; we must provide a term of type &lt;code    &gt;[a]&lt;/code    &gt;. However, we know nothing concrete about &lt;code    &gt;a&lt;/code    &gt;, since it's an argument passed in from the outside. So we can return an empty list&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;term1 = &amp;#923;a. []&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;or an undefined value&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;term1 = &amp;#923;a. &amp;#8869;@[a]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;or a list containing undefined values only&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;term1 = &amp;#923;a. [&amp;#8869;@a, &amp;#8869;@a]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;but not much else.&lt;/p  &gt;&lt;p  &gt;To use this value, we apply a type, removing the outer ∀. Let's arbitrarily instantiate &lt;code    &gt;&amp;#8704;a. [a]&lt;/code    &gt; to &lt;code    &gt;[Bool]&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;main = &lt;/span      &gt;&lt;span class="Function"      &gt;print&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @Int (&lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @Bool (term1 @Bool))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;pre  &gt;&lt;code    &gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="a.-a-1"&gt;&lt;h1  &gt;[∀a. a]&lt;/h1  &gt;&lt;p  &gt;What about &lt;code    &gt;[&amp;#8704;a. a]&lt;/code    &gt;, then? If ∀ signifies a function on types, then &lt;code    &gt;[&amp;#8704;a. a]&lt;/code    &gt; is a list of functions. We can provide as few as we like:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;term2 ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [&amp;#8704;a. a]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term2 = []&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;or as many:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;term2 = [f, g, h]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;But what are our choices for &lt;code    &gt;f&lt;/code    &gt;, &lt;code    &gt;g&lt;/code    &gt;, and &lt;code    &gt;h&lt;/code    &gt;?&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;f ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &amp;#8704;a. a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;f = &amp;#923;a. ?&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Now we're well and truly stuck. We have to provide a value of type &lt;code    &gt;a&lt;/code    &gt;, but we know nothing whatsoever about the type &lt;code    &gt;a&lt;/code    &gt;. So our only choice is&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;f = &amp;#923;a. &amp;#8869;@a&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;So our options for &lt;code    &gt;term2&lt;/code    &gt; look like&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;term2 ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; [&amp;#8704;a. a]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term2 = []&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term2 = [&amp;#923;a. &amp;#8869;@a]&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term2 = [&amp;#923;a. &amp;#8869;@a, &amp;#923;a. &amp;#8869;@a]&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;etc. And let's not forget&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;term2 = &amp;#8869;@(&amp;#8704;a. [a])&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Unlike the previous example, our choices for &lt;code    &gt;term2&lt;/code    &gt; are already lists, and we can pass them to &lt;code    &gt;length&lt;/code    &gt; directly. As before, we have to pass the element type to &lt;code    &gt;length&lt;/code    &gt;:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;main = &lt;/span      &gt;&lt;span class="Function"      &gt;print&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @Int (&lt;/span      &gt;&lt;span class="Function"      &gt;length&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @(&amp;#8704;a. a) term2)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;pre  &gt;&lt;code    &gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="existential-types"&gt;&lt;h1  &gt;Existential types&lt;/h1  &gt;&lt;p  &gt;So a value of universal (∀) type is a function from types to values. A value of existential (∃) type is a &lt;em    &gt;pair&lt;/em    &gt; of a type and a value.&lt;/p  &gt;&lt;p  &gt;More specifically: A value of type&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;&amp;#8707;x. T&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;is a pair&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;(S, v)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;where S is a type, and where &lt;code    &gt;v :: T&lt;/code    &gt;, assuming you bind the type variable &lt;code    &gt;x&lt;/code    &gt; to &lt;code    &gt;S&lt;/code    &gt; within &lt;code    &gt;T&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;Here's an existential type signature and a few terms with that type:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;term3 ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; &amp;#8707;a. a&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term3 = (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,         &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;3&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term3 = (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Char&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,        &lt;/span      &gt;&lt;span class="Char"      &gt;'x'&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term3 = (&amp;#8704;a. a &amp;#8594; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, &amp;#923;a. &amp;#955;(&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;x::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;a). &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;4&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;In other words, we can put any value we like into &lt;code    &gt;&amp;#8707;a. a&lt;/code    &gt;, as long as we pair that value with its type.&lt;/p  &gt;&lt;p  &gt;The &lt;em    &gt;user&lt;/em    &gt; of a value of type &lt;code    &gt;&amp;#8704;a. a&lt;/code    &gt; is in a great position; they can choose any specific type they like, using the type application &lt;code    &gt;@T&lt;/code    &gt;, to obtain a term of type &lt;code    &gt;T&lt;/code    &gt;. The &lt;em    &gt;producer&lt;/em    &gt; of a value of type &lt;code    &gt;&amp;#8704;a. a&lt;/code    &gt; is in a terrible position: they must be prepared to produce any type asked for, so (as in the previous section) the only choice is &lt;code    &gt;&amp;#923;a. &amp;#8869;@a&lt;/code    &gt;.&lt;/p  &gt;&lt;p  &gt;The &lt;em    &gt;user&lt;/em    &gt; of a value of type &lt;code    &gt;&amp;#8707;a. a&lt;/code    &gt; is in a terrible position; the value inside is of some unknown specific type, not a flexible polymorphic value. The &lt;em    &gt;producer&lt;/em    &gt; of a value of type &lt;code    &gt;&amp;#8707;a. a&lt;/code    &gt; is in a great position; they can stick any value they like into the pair, as we saw above.&lt;/p  &gt;&lt;p  &gt;So what's a less useless existential? How about values paired with a binary operation:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;type&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something = &amp;#8707;a. (a, a &amp;#8594; a &amp;#8594; a, a &amp;#8594; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term4_a, &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;term4_b ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term4_a = (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;Int&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,    (&lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;,     (+)  @Int , &lt;/span      &gt;&lt;span class="Function"      &gt;show&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; @Int))&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term4_b = (&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, (&lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;foo&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;, (++) @Char, &amp;#955;(&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;x::&lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;). x))&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Using it:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Function FunctionDefinition"      &gt;triple ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something &amp;#8594; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;triple = &amp;#955;(a, (&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;x ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a, &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;f ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a&amp;#8594;a&amp;#8594;a, &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;out ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a&amp;#8594;String)).&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;  out (f (f x x) x)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;The result:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;triple term4_a  &amp;#8658;  &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;3&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;triple term4_b  &amp;#8658;  &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;foofoofoo&amp;quot;&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;We've packaged up a type and some operations on that type. The user can apply our operations but cannot inspect the concrete value — we can't pattern-match on &lt;code    &gt;x&lt;/code    &gt; within &lt;code    &gt;triple&lt;/code    &gt;, since its type (hence set of constructors) is unknown. This is more than a bit like object-oriented programming.&lt;/p  &gt;&lt;/div&gt;&lt;div id="using-existentials-for-real"&gt;&lt;h1  &gt;Using existentials for real&lt;/h1  &gt;&lt;p  &gt;The direct syntax for existentials using ∃ and type-value pairs would be quite convenient. &lt;a href="http://www.cs.uu.nl/wiki/UHC"    &gt;UHC&lt;/a    &gt; partially supports this direct syntax. But GHC does not. To introduce existentials in GHC we need to define new &amp;quot;wrapper&amp;quot; types.&lt;/p  &gt;&lt;p  &gt;Translating the above example:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Comment"      &gt;{-# LANGUAGE ExistentialQuantification #-}&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something = forall a. MkThing a (a -&amp;gt; a -&amp;gt; a) (a -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;)&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term_a, &lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;term_b ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term_a = MkThing &lt;/span      &gt;&lt;span class="DecVal Decimal"      &gt;1&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (+) &lt;/span      &gt;&lt;span class="Function"      &gt;show&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;term_b = MkThing &lt;/span      &gt;&lt;span class="String"      &gt;&amp;quot;foo&amp;quot;&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; (++) &lt;/span      &gt;&lt;span class="Function"      &gt;id&lt;/span      &gt;&lt;br       /&gt;&lt;br       /&gt;&lt;span class="Function FunctionDefinition"      &gt;triple ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; Something -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;br       /&gt;&lt;span class="Normal NormalText"      &gt;triple (MkThing x f out) = out (f (f x x) x)&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;There's a couple differences from our theoretical treatment. Type application, type abstraction, and type pairs are again implicit. Also, the wrapper is confusingly written with &lt;code    &gt;forall&lt;/code    &gt; rather than &lt;code    &gt;exists&lt;/code    &gt;. This references the fact that we're declaring an &lt;em    &gt;existential&lt;/em    &gt; type, but the &lt;em    &gt;data constructor&lt;/em    &gt; has &lt;em    &gt;universal&lt;/em    &gt; type:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Normal NormalText"      &gt;M&lt;/span      &gt;&lt;span class="Function FunctionDefinition"      &gt;kThing ::&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; forall a. a -&amp;gt; (a -&amp;gt; a -&amp;gt; a) -&amp;gt; (a -&amp;gt; &lt;/span      &gt;&lt;span class="DataType TypeConstructor"      &gt;String&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt;) -&amp;gt; Something&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;p  &gt;Often, we use existential quantification to &amp;quot;capture&amp;quot; a type class constraint. We could do something similar here:&lt;/p  &gt;&lt;pre class="sourceCode haskell"  &gt;&lt;code    &gt;&lt;span class="Keyword"      &gt;data&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; SomeMonoid = forall a. (Monoid a, &lt;/span      &gt;&lt;span class="Keyword Class"      &gt;Show&lt;/span      &gt;&lt;span class="Normal NormalText"      &gt; a) =&amp;gt; MkMonoid a&lt;/span      &gt;&lt;br       /&gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;pre  &gt;&lt;code    &gt;&lt;/code    &gt;&lt;/pre  &gt;&lt;/div&gt;&lt;div id="further-reading"&gt;&lt;h1  &gt;Further reading&lt;/h1  &gt;&lt;p  &gt;For an introduction to the theory, I highly recommend &lt;em    &gt;&lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/"      &gt;Types and Programming Languages&lt;/a      &gt;&lt;/em    &gt; by Pierce. For a discussion of existential types in GHC, see &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/data-type-extensions.html#existential-quantification"    &gt;the GHC manual&lt;/a    &gt; and &lt;a href="http://www.haskell.org/haskellwiki/Existential_type"    &gt;the Haskell wiki&lt;/a    &gt;.&lt;/p  &gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1563623855220143059-1507115966516523671?l=mainisusuallyafunction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mainisusuallyafunction.blogspot.com/feeds/1507115966516523671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/quantification-in-haskell.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/1507115966516523671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1563623855220143059/posts/default/1507115966516523671'/><link rel='alternate' type='text/html' href='http://mainisusuallyafunction.blogspot.com/2010/10/quantification-in-haskell.html' title='Quantification in Haskell'/><author><name>keegan</name><uri>http://www.blogger.com/profile/12227260241426017476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1563623855220143059.post-740533893647733515</id><published>2010-10-18T23:15:00.000-07:00</published><updated>2010-10-18T23:15:38.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='imadethis'/><category scheme='http://www.blogger.com/atom/ns#' term='jvf2010a'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Programming the JVF 2010-A</title><content type='html'>&lt;p&gt;The JVF 2010-A is a large electronic sign consisting of 128 × 48 red LEDs.&lt;/p&gt;&lt;p&gt;There is some information online about the official software provided with this sign. There's less information about the hardware, or how to write custom software. Here's what I've learned on these subjects. If you're itching to start hacking, skip to the end for downloadable C code.&lt;/p&gt;&lt;p&gt;The sign I worked on lives at &lt;a href="http://miters.mit.edu/"  &gt;MITERS&lt;/a  &gt;. There is a similar sign at &lt;a href="https://www.noisebridge.net/"  &gt;Noisebridge&lt;/a  &gt;. See &lt;a href="https://www.noisebridge.net/wiki/Big_LED_Screen"  &gt;their writeup&lt;/a  &gt; for pictures and more hardware description.&lt;/p&gt;&lt;div id="hardware"&gt;&lt;h1  &gt;Hardware&lt;/h1  &gt;&lt;p  &gt;The removable back panel of the unit holds three circuit boards: a PC motherboard, a power supply, and a custom board I'll call the LED controller.&lt;/p  &gt;&lt;p  &gt;The motherboard has a 386-compatible (?) processor, some RAM sticks, and a number of ISA slots. One slot provides a connector to the floppy drive, as well as an unused hard-drive connector. Another slot connects directly to the LED controller by a ribbon cable. The motherboard also holds a DIN-5 connector which I presume to be for an AT keyboard. I could not find any serial or parallel ports even as pin headers, though they could be added on an ISA card.&lt;/p  &gt;&lt;p  &gt;The LED controller is a large custom board of DIP integrated circuits. Other than two 16kbit SRAM chips, all of the logic is provided by 74-series discrete logic ICs. There is not a processor or PLD to be found. This board connects to other boards attached to the front of the unit, which I did not investigate further.&lt;/p  &gt;&lt;p  &gt;Lacking a logic analyzer, I decided to investigate the software side.&lt;/p  &gt;&lt;/div&gt;&lt;div id="reverse-engineering-the-software"&gt;&lt;h1  &gt;Reverse-engineering the software&lt;/h1  &gt;&lt;p  &gt;I acquired a copy of the official software, &lt;code    &gt;JVFF.EXE&lt;/code    &gt;. The software runs fine in &lt;a href="http://www.dosbox.com/"    &gt;DOSBox&lt;/a    &gt;. It even displays output: there's a fallback which draws CGA graphics if no LED board is found.&lt;/p  &gt;&lt;p  &gt;I enabled IO port logging in DOSBox, by setting &lt;code    &gt;#define ENABLE_PORTLOG&lt;/code    &gt; in &lt;code    &gt;src/hardware/iohandler.cpp&lt;/code    &gt;. I noticed a read from port &lt;code    &gt;0x2F0&lt;/code    &gt;, which is not listed as a standard port in &lt;a href="http://www.cs.cmu.edu/~ralf/files.html"    &gt;RBIL&lt;/a    &gt;. DOSBox helpfully logs the instruction pointer with each port access, and soon I was reading the executable's assembly code in the freeware version of IDA. I found the following interesting functions:&lt;/p  &gt;&lt;ul class="incremental"  &gt;&lt;li    &gt;&lt;p      &gt;&lt;strong &gt;&lt;code   &gt;0x4050&lt;/code   &gt;&lt;/strong &gt;: Reads a configuration byte from the controller at port &lt;code &gt;0x2F0&lt;/code &gt;. This byte specifies which DMA channel to use, as well as the dimensions of the display.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;strong &gt;&lt;code   &gt;0x3F02&lt;/code   &gt;&lt;/strong &gt;: The entry point for updating the display. Called from many places. Takes a range of lines to update (?) as arguments. Depending on some global variables, it calls &lt;code &gt;0x3FA9&lt;/code &gt; and/or the CGA drawing routine.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;strong &gt;&lt;code   &gt;0x3FA9&lt;/code   &gt;&lt;/strong &gt;: The &amp;quot;driver&amp;quot; for the LED controller. Calls all of the below.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;strong &gt;&lt;code   &gt;0x410D&lt;/code   &gt;&lt;/strong &gt;: Sets up a DMA transfer to the controller, then writes the three bytes &lt;code &gt;0x8F&lt;/code &gt;, &lt;code &gt;0x0F&lt;/code &gt;, &lt;code &gt;0x07&lt;/code &gt; to the controller at port &lt;code &gt;0x2F0&lt;/code &gt;.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;strong &gt;&lt;code   &gt;0x417A&lt;/code   &gt;&lt;/strong &gt;: Checks whether the DMA transfer has completed.&lt;/p      &gt;&lt;/li    &gt;&lt;li    &gt;&lt;p      &gt;&lt;stron
